로컬 네트워크 액세스

커뮤니티 그룹 보고서 초안,

이 문서에 대한 자세한 정보
이 버전:
https://wicg.github.io/local-network-access/
이슈 추적:
GitHub
명세 내 인라인
편집자:
(Google)
(Google)

초록

새 권한으로 사용자의 로컬 네트워크에 대한 접근을 제한한다

이 문서의 상태

1. 소개

이 절은 규범적이지 않다.

[RFC1918]가 20년 넘게 "private" 인터넷 주소와 "public" 인터넷 주소를 구분하도록 명시해 왔지만, 사용자 에이전트는 둘을 서로 분리하는 데 큰 진전을 이루지 못했다. public 인터넷의 웹사이트는 로컬 기기 및 서버에 요청을 보낼 수 있으며, 이는 [DRIVE-BY-PHARMING], [SOHO-PHARMING][CSRF-EXPLOIT-KIT]에 문서화된 것과 같은 사용자 라우터에 대한 공격을 포함하여 여러 악의적 동작을 가능하게 한다.

Local Network Access는 로컬 네트워크의 안전하지 않은 기기로 향하는 이러한 원치 않는 요청을 방지하는 것을 목표로 한다. 이는 public 웹사이트에서 로컬 IP 주소로의 직접 접근을 폐기하고, 대신 사용자가 시작 웹사이트에 자신의 로컬 네트워크로 연결을 만들 수 있는 권한을 부여하도록 요구함으로써 달성된다.

Note: 이 제안은 Chrome의 이전에 일시 중단된 [PRIVATE-NETWORK-ACCESS] 작업 위에 구축되지만, preflight 요청을 통하지 않고 권한에 따라 접근을 제어한다는 점에서 다르다.

1.1. 목표

전반적인 목표는 사용자 에이전트가 사용자의 로컬 인트라넷에서 실행되는 기기 또는 사용자의 머신에서 직접 실행되는 서비스에 대한 공격을 부주의하게 가능하게 하지 않도록 방지하는 것이다. 예를 들어, 다음에 대한 공격을 완화하고자 한다:

사용자가 로컬 네트워크 접근 요청이 발생할 것을 기대하고 명시적으로 허용하는 경우 이러한 요청을 허용하기 위한 잘 드러난 경로가 있어야 한다. 예를 들어, plex.tv에 로그인한 사용자는 사이트가 원격 서버를 거치지 않고 로컬 네트워크를 통해 미디어 콘텐츠를 직접 로드하기 위해 자신의 로컬 미디어 서버에 연결하도록 허용하고 싶을 수 있다. 더 많은 예는 아래 § 1.3 예제를 참조하라.

1.2. 비목표

이 명세는 로컬 네트워크 기기에서 HTTPS 연결을 더 쉽게 사용할 수 있게 하려고 시도하지 않는다. 이것은 유용한 목표일 수 있지만, 이 문제를 해결하는 것은 이 명세의 범위를 벗어난다

1.3. 예제

1.3.1. 사용자의 권한 허용

Alice는 집에서 노트북으로 인터넷을 탐색하고 있다. 그녀의 로컬 네트워크에는 Acme Printing Company가 만든 프린터가 있으며, 이 프린터는 간단한 HTTP 서버를 실행하고 있다. Alice는 프린터가 제대로 작동하지 않는 문제를 겪고 있다.

Alice는 문제 진단을 돕기 위해 Acme Printing Company의 웹사이트로 이동한다. Acme Printing Company의 웹사이트는 프린터에 연결하여 프린터의 진단 출력을 살펴볼 수 있다고 Alice에게 알려준다. Alice의 브라우저는 Alice에게 https://support.acmeprintingcompany.com이 그녀의 네트워크에 있는 로컬 기기에 연결하도록 허용할지 묻는다. Alice는 https://support.acmeprintingcompany.com이 그녀의 네트워크에 있는 로컬 기기에 연결하는 것을 허용하고, https://support.acmeprintingcompany.com은 그녀의 로컬 프린터의 진단 출력에 연결하여, 프린터의 부품 하나가 오작동하고 있어 교체해야 한다고 Alice에게 알려준다.

1.3.2. 사용자의 권한 거부

Alice는 자신의 프린터 교체 부품을 가장 좋은 가격으로 찾기 위해 온라인 탐색을 계속한다. 일반적인 기술 지원 포럼을 보던 중, 갑자기 브라우저에서 https://printersupport.evil.com이 그녀의 로컬 네트워크에 있는 로컬 기기에 연결하도록 허용할지 묻는 권한 요청을 받는다. 왜 https://printersupport.evil.com이 로컬 기기에 연결해야 하는지 의심스러웠기 때문에, 그녀는 권한 요청을 거부한다.

1.3.3. 새 기기 구성

프린터의 부품을 교체하는 대신, Alice는 Beta Manufacturing에서 새 프린터를 구입하기로 한다. 프린터를 꽂고 로컬 네트워크에 연결한 뒤, Alice는 안내에 따라 노트북에서 https://setup.betaprinters.com으로 이동한다. 사이트를 열자 프린터 기본값 설정을 도와주는 버튼이 보인다. 버튼을 누르자, https://setup.betaprinters.com이 그녀의 로컬 기기에 연결할 수 있도록 권한을 요청하는 프롬프트가 나타나고, 그녀는 이를 수락한다.

1.3.4. 앱 기반 로그인

Alice는 직장에서 제한된 작업 집합에 자신의 개인 기기를 사용한다. 고용주는 이러한 기본 작업에 대해 기기 관리를 요구하지 않지만, 강력한 자격 증명과 제한된 기기 컨텍스트 집합을 제공하는 인증 앱 설치를 요구한다. Alice가 업무 사이트에 접근하려고 하면, 회사의 단일 로그인 서비스인 login.myco.com으로 리디렉션되고 앱을 사용해 로그인하라는 요청을 받는다. 웹사이트는 로컬 앱이 사용하는 주소인 http://localhost:45678로 fetch 요청을 만든다. Alice는 https://login.myco.com이 로컬 기기와 연결하도록 허용할지 묻는 프롬프트를 보고 이를 수락한다. 앱이 호출되고, Alice는 기기 잠금 해제를 사용해 앱에 인증하라는 요청을 받는다.

2. 프레임워크

2.1. IP 주소 공간

IPAddressSpace를 다음과 같이 정의한다:

enum IPAddressSpace { "public", "local", "loopback" };

모든 IP 주소는 세 가지 값 중 하나일 수 있는 IP 주소 공간에 속한다:

  1. loopback: 로컬 호스트에서만 접근할 수 있는 루프백 주소를 포함한다. 즉, 대상이 모든 기기마다 다른 주소이다.

  2. local: 현재 네트워크 내에서만 의미가 있는 주소를 포함한다. 즉, 네트워크 위치에 따라 대상이 달라지는 주소이다.

  3. public: 그 밖의 모든 주소를 포함한다. 즉, IP 네트워크에서 전 세계 모든 기기에 대해 대상이 동일한 주소이다.

편의를 위해 다음 용어도 정의한다:

  1. 루프백 주소는 그 IP 주소 공간loopback인 IP 주소이다.

  2. 로컬 주소는 그 IP 주소 공간local인 IP 주소이다.

  3. 공용 주소는 그 IP 주소 공간public인 IP 주소이다.

IP 주소 공간 lhs는 다음 조건 중 하나가 참이면 IP 주소 공간 rhs보다 덜 공용이다:

  1. lhsloopback이고 rhslocal 또는 public이다.

  2. lhslocal이고 rhspublic이다.

IP 주소 addressIP 주소 공간을 결정하려면 다음 단계를 실행한다:

  1. address::ffff:0:0/96 "IPv4-mapped Address" 주소 블록에 속하면, address를 그 안에 포함된 IPv4 주소로 바꾼다.

  2. 비공용 IP 주소 블록 표의 각 row에 대해:

    1. addressrow의 주소 블록에 속하면, row의 주소 공간을 반환한다.

  3. public을 반환한다.

비공용 IP 주소 블록
주소 블록 이름 참조 주소 공간
127.0.0.0/8 IPv4 루프백 [RFC1122] loopback
10.0.0.0/8 사설 사용 [RFC1918] local
100.64.0.0/10 Carrier-Grade NAT [RFC6598] local
172.16.0.0/12 사설 사용 [RFC1918] local
192.168.0.0/16 사설 사용 [RFC1918] local
198.18.0.0/15 벤치마킹 [RFC2544] loopback
169.254.0.0/16 링크 로컬 [RFC3927] local
::1/128 IPv6 루프백 [RFC4291] loopback
fc00::/7 고유 로컬 [RFC4193] local
fe80::/10 링크 로컬 유니캐스트 [RFC4291] local
fec0::/10 사이트 로컬 유니캐스트 [RFC3513] local
0.0.0.0/32 IPv4 null IP 주소 [RFC1884] loopback
0.0.0.0/8 IPv4 null IP 주소들 [RFC1884] local
::/128 IPv6 지정되지 않은 주소 [RFC1884] loopback
2001:db8::/32 IPv6 문서화 주소 [RFC3849] local
3fff::/20 IPv6 문서화 주소 [RFC9637] local
::ffff:0:0/96 IPv4-mapped [RFC4291] 매핑된 IPv4 주소 참조

사용자 에이전트는 특정 IP 주소 블록의 주소 공간이 관리자 또는 사용자 구성에 의해 재정의되도록 허용할 수 있다. 이는 예를 들어 위 알고리즘에 따르면 대부분의 IP 주소가 public으로 간주되는 IPv6 인트라넷을 보호하는 데 유용할 수 있으며, 대신 사용자 에이전트가 해당 인트라넷을 local로 취급하도록 구성할 수 있다.

Note: 169.254.0.0/16과 같은 링크 로컬 IP 주소는 local로 간주된다. 이러한 주소는 네트워크 링크의 모든 기기에 대해 같은 대상을 식별할 수 있기 때문이다. 이 명세의 이전 버전에서는 이를 대신 loopback으로 간주했다.

Note:IP 주소 공간의 내용은 한때 IANA Special-Purpose Address Registries ([IPV4-REGISTRY][IPV6-REGISTRY])와 그 안에서 정의된 Globally Reachable 비트에 따라 결정되었다. 이는 우리의 용도에는 부정확한 신호로 드러났으며, wicg/private-network-access issue #50에 설명되어 있다.

Note: [PRIVATE-NETWORK-ACCESS]는 주소 공간 public, private, local을 사용했다. 이 명세는 해당 주소 공간의 이름을 각각 public, local, loopback으로 바꾼다.

Note: [FETCH]는 null IP 주소에 대한 요청을 네트워크 오류로 취급하도록 명시할 예정이다. 우리는 IPv4 null IP 주소 공간과 IPv6 지정되지 않은 주소를 모두 loopback으로 매핑한다. 일부 시스템에서는 여전히 이를 로컬 호스트 머신으로 라우팅할 수 있기 때문이다(그리고 0.0.0.0/8은 "이 네트워크의 지정된 호스트"를 가리킬 수 있으므로 local로 매핑된다). 이는 [RFC5735]에 따른다. Fetch의 변경이 이루어지고 채택되면, 우리는 더 이상 이 명세에서 이를 처리할 필요가 없게 된다.

2.2. 로컬 네트워크 요청

요청 (request)은 request현재 urlhost가 IP 주소로 매핑되고, 그 IP 주소 공간requestpolicy containerIP 주소 공간보다 덜 공용이면 로컬 네트워크 요청이다.

IP 주소를 두 개의 넓은 주소 공간으로 분류하는 것은 불완전하고 이론적으로 견고하지 않은 접근이다. 이는 두 네트워크 엔드포인트가 자유롭게 통신해도 되는지, 즉 엔드포인트 A가 엔드포인트 C의 사용자 에이전트를 통해 우회하지 않고 엔드포인트 B에서 도달 가능한지를 판단하는 데 사용되는 프록시이다.

이 접근에는 몇 가지 결함이 있다:

그럼에도 이 명세는 네트워크 구성이 그렇게 복잡하지 않은 대부분의 웹 사용자에게 광범위하게 영향을 미치는 보안 문제에 대해 실용적인 해결책을 제공하는 것을 목표로 한다.

루프백 주소에서 발생한 요청은 로컬 네트워크 요청으로 간주해서는 안 되며, 로컬 네트워크 접근 검사 대상이 되어서는 안 된다. 사용자의 기기에서 실행되는 모든 소프트웨어는 이미 사용자의 네트워크에서 가장 특권적인 관점에 있기 때문이다.

로컬 네트워크 요청의 정의는 현재 urlhost가 IP 주소로 매핑되고, 그 IP 주소 공간public이 아닌 모든 교차 출처 요청을 포괄하도록 확장될 수 있다. 이는 로컬 네트워크의 악의적 서버가 localhost의 서버를 포함한 다른 서버를 공격하는 것을 방지할 것이다. wicg/private-network-access issue #39를 참조하라.

NOTE: 현재 Chromium은 public에서 local 또는 loopback으로 향하는 요청에 대해서만 Local Network Access 제한을 구현하며, 교차 출처 local 요청에는 권한을 강제하지 않는다. 이 제한은 향후 구현에서 점진적 개선으로 출시될 수 있다.

NOTE: 로컬 이름과 주소는 네트워크의 범위 밖에서는 의미가 없기 때문에, 구현자는 교차 출처 local 사례에 대해 public에서 local로 향하는 사례와는 다른 권한 프롬프트를 사용하고자 할 수 있다. 또한 구현자는 이러한 권한 부여의 범위를 특정 네트워크 또는 현재 탐색 세션으로만 제한하고자 할 수 있다.

NOTE: 일부 로컬 네트워크 요청은 다른 것보다 보호하기 더 어렵다. 자세한 내용은 § 4.4 출시 어려움을 참조하라.

2.3. 로컬 네트워크 요청 권한 프롬프트

public 웹사이트에서 로컬 네트워크 서버로 보내는 로컬 네트워크 요청을 사용자가 승인할 수 있도록 로컬 네트워크 접근 권한 프롬프트가 도입된다.

로컬 네트워크 요청이 감지되면, 로컬 네트워크에 접근할 권한을 요청하는 프롬프트가 사용자에게 표시된다. 사용자가 권한을 부여하기로 결정하면 fetch는 계속된다. 그렇지 않으면 실패한다.

권한의 정확한 범위는 구현 정의이다. 권한은 특정 출처가 로컬 네트워크의 모든 엔드포인트에 로컬 네트워크 요청을 보낼 수 있도록 허용하는 정도로 거칠 수도 있고, 특정 출처가 로컬 네트워크의 특정 엔드포인트와만 통신하도록 허용하는 정도로 더 세분화될 수도 있다. 사용자 에이전트는 권한 피로를 줄이기 위해 이 결정을 지속할 수 있다.

2.4. 보안 컨텍스트 제한

로컬 네트워크 요청을 만들 수 있는 기능은 강력한 기능이며, 보안 컨텍스트에서만 허용되어야 한다.

향후 모든 교차 출처 local 요청에 LNA 검사를 적용할 수 있도록(위 이슈 참조), Chromium은 현재 공개적으로 신뢰되는 HTTPS 인증서를 얻기 어려울 가능성이 큰 로컬 서버(예: .local의 서버와 사설 IP 리터럴)를 이 요구사항에서 제외할 계획이다. 더 많은 논의는 § 4.4 출시 어려움을 참조하고, 또한 wicg/private-network-access issue #96도 참조하라.

2.5. 혼합 콘텐츠

많은 로컬 네트워크 서버는 HTTPS를 실행하지 않는다. 로컬 네트워크 서버를 HTTP에서 이전하는 것이 어렵고(때로는 불가능하기까지) 입증되었기 때문이다. 이는 보안 컨텍스트 제한이 혼합 콘텐츠 검사와 결합되어, 사용자가 요청이 발생하도록 권한을 부여하더라도 많은 로컬 네트워크 요청을 차단한다는 점에서 문제가 된다.

이 문제의 한 가지 해결책은 요청이 로컬 네트워크 요청임을 알고 있는 상황에서 혼합 콘텐츠 검사를 우회하는 것이다. 이는 몇 가지 상황에서 알려져 있다:

위 두 상황 중 어느 것도 참이 아니지만, 사이트가 요청을 로컬 네트워크 요청으로 식별하고자 하는 상황이 있을 수 있다. 이는 fetch() 옵션 bag에 새 매개변수를 추가하여 완화할 수 있다:

fetch("http://router.local/ping", {
  targetAddressSpace: "local",
});

이는 브라우저에 scheme이 안전하지 않더라도 fetch가 혼합 콘텐츠 검사를 우회하고 대상 서버에 대한 연결을 잠재적으로 얻도록 허용하라고 지시한다. 새로운 fetch() API는 하위 호환된다.

이 기능은 일반적인 혼합 콘텐츠를 우회하는 데 악용될 수 없다는 점에 유의하라. 해석된 원격 IP 주소가 targetAddressSpace 옵션 값으로 지정된 IP 주소 공간에 속하지 않으면 요청은 실패한다. 속한다면, 권한을 검사하여 요청을 허용하거나 실패시킬 수 있다.

Chromium은 현재 비표준 CSP 지시어 treat-as-public-address를 지원한다 (private-network-access#csp 참조). wicg/private-network-access issue #39가 구현되면 이 지시어는 불필요해질 것이다.

2.6. 권한

이 문서는 다음 기본 강력한 기능을 정의한다. 이들은 정책 제어 기능이며 기본 allowlist'self'이다:

NOTE: 이전에는 이것이 local과 loopback 사례를 모두 포괄하는 단일 기본 강력한 기능, "local-network-access"로 명시되었다. Chromium은 여전히 이를 새로운 세분화된 권한 이름의 별칭으로, 그리고 정책 제어 기능 이름으로 사용할 수 있도록 지원한다.

2.7. treat-as-public-address 콘텐츠 보안 정책 지시문

treat-as-public-address 지시문은 사용자 에이전트에게 문서를 실제로는 로컬 주소 또는 루프백 주소에서 제공되었더라도 공개 주소에서 제공된 것처럼 취급하라고 지시한다. 즉, 이는 비공개 문서가 프리플라이트 없이 다른 비공개 문서에 접촉할 수 있는 권한을 내려놓을 수 있게 하는 메커니즘이다.

이 지시문의 구문은 다음 ABNF 문법으로 설명된다:

directive-name  = "treat-as-public-address"
directive-value = ""

이 지시문에는 보고 요구사항이 없으며, Content-Security-Policy-Report-Only 헤더로 전달되거나 <meta> 요소 내에서 전달될 때는 완전히 무시된다.

이 지시문의 초기화 알고리즘은 다음과 같다. 주어진 환경 설정 객체(context), Response(response) 및 policy에 대해:

  1. policydisposition이 "enforce"이면, context정책 컨테이너IP address spacepublic으로 설정한다.

https://github.com/WICG/private-network-access/issues/88 은 이를 CSP 지시문에서 다른 위치로 옮길 것을 권고했다.

3. 통합

이 절은 비규범적이다.

이 문서는 위에서 설명한 보호를 구현하기 위해 다른 명세에 대한 여러 수정을 제안한다. 이러한 통합은 명확성을 위해 여기에 개요로 제시되지만, 외부 문서가 규범적 참조이다.

3.1. Fetch와의 통합

이 문서는 [FETCH]에 몇 가지 변경을 제안하며, 그 의미는 다음과 같다: 로컬 네트워크 요청은 그 client보안 컨텍스트이고 또한 사용자가 권한을 부여한 경우에만 허용된다. 요청이 혼합 콘텐츠로 차단되었을 경우에도, 웹사이트가 로컬 네트워크에 접근하려는 의도를 명시하고 사용자가 권한을 부여하면 허용될 수 있다.

Note: 여기에는 탐색도 포함된다. 탐색은 하위 리소스 요청보다 덜 은밀하지만 CSRF 공격을 트리거하는 데 실제로 사용될 수 있다.

Chromium은 현재 LNA 제한을 iframe 탐색에만 적용한다. 이를 메인 프레임 탐색(특히 opener에 의해 제어될 수 있는 팝업 창)까지 확장할 가치가 있을 수 있다.

Note: [FETCH]는 아직 DNS 해석의 세부 사항을 Fetch 알고리즘에 통합하지 않았지만, 이 명세에 충분한 연결 획득 알고리즘을 정의한다. Local Network Access 검사는 새로 획득한 연결에 적용된다. Happy Eyeballs ([RFC6555], [RFC8305])와 같은 복잡성으로 인해, 여러 IP 주소가 IP 주소 공간 경계를 가로지르는 호스트에서는 이러한 검사가 비결정적으로 통과하거나 실패할 수 있다.

3.1.1. 페칭

NOTE: [FETCH]의 연결 관리는 의도적으로 다소 모호하므로, 아래 일부 내용은 구현자를 위한 note를 통해 설명된다. 이 절은 구현자가 연결을 획득한 후, 그 연결을 사용해 fetch를 계속 수행하기 전에 로컬 네트워크 접근 검사를 수행함을 제시한다.

wicg/local-network-access issue #103를 해결하려면, 대신 출처를 해석한 뒤 실제 연결을 만들기 전에 검사를 수행하도록 연결 획득의 4.6단계에 통합해야 한다.

[FETCH]를 다음과 같이 갱신한다:

  1. Connection 객체에는 새 IP address 속성이 주어진다. 그 값은 null 또는 IP 주소이고, 초기값은 null이다.

  2. create a connection 알고리즘에서 새 연결을 설정한 직후(2단계와 3단계 사이)에 새 단계를 추가한다.

    1. hostIP 주소이면, connectionIP addresshost로 설정한다.

  3. Request 객체에는 새 target IP address space 속성이 주어지며, 초기값은 null이다.

  4. Response 객체에는 새 IP address 속성이 주어진다. 그 값은 null 또는 IP 주소이고, 초기값은 null이다.

  5. Local Network Access check 알고리즘을 정의한다. request requestIP 주소 address가 주어졌을 때:

    NOTE: 이 알고리즘은 IP 주소를 받으므로 HTTP-network fetch(connection이 있는 곳) 또는 HTTP-network-or-cache fetch(저장된 response에 저장된 IP 주소가 있는 곳)에서 호출될 수 있다. 이는 매핑이 사용자 에이전트에 의해 동적으로 갱신될 수 있으므로 매번 IP 주소 공간을 의도적으로 다시 계산한다.

    1. address에 대해 IP 주소 공간을 결정 알고리즘을 실행한 결과를 addressSpace라고 한다.

    2. requestorigin잠재적으로 신뢰할 수 있는 출처이고, requestcurrent URLoriginrequestoriginsame origin이면, null을 반환한다.

    3. requestpolicy container가 null이면, null을 반환한다.

      NOTE: requestpolicy container가 null이면, LNA 검사는 request에 적용되지 않는다. fetch 알고리즘의 사용자는 requestclient를 null이 아닌 policy container를 가진 environment settings object로 설정하고 fetchrequestpolicy container를 그에 따라 초기화하도록 하거나, 또는 requestpolicy container를 null이 아닌 값으로 직접 설정하도록 주의해야 한다.

    4. requesttarget IP address space가 null이 아니면:

      1. Assert: requesttarget IP address spacepublic이 아니다.

      2. addressSpacerequesttarget IP address space와 같지 않으면, network error를 반환한다.

      3. null을 반환한다.

    5. addressSpacerequestpolicy containerIP 주소 공간보다 덜 공용이면:

      1. errornetwork error로 둔다.

      2. requestclient보안 컨텍스트가 아니면 (null인 경우를 포함하여), error를 반환한다.

      3. errorIP address 속성을 address로 설정한다.

      4. addressSpacelocal이면 permissionName을 "local-network"로, addressSpaceloopback이면 "loopback-network"로 둔다.

      5. settingsObjectrequestclient로 둔다.

      6. globalsettingsObjectglobal object로 둔다.

      7. documentglobalassociated Document로 둔다.

      8. document가 null이면 error를 반환한다.

        NOTE: Service Worker는 항상 associated Document를 가지는 것은 아니므로, 이 단계는 Service Worker에서 발생한 로컬 네트워크 요청을 실패하게 만든다. 이 명세의 향후 버전은 Worker를 처리하는 방법을 정의해야 하며, 특히 Permissions Policy가 아직 Worker에서 지원되지 않는다는 점이 중요하다. w3c/webappsec-permissions-policy#207를 참조하라.

        Service Worker의 로컬 네트워크 접근 동작을 정의하라.

      9. documentpermissionName사용할 수 있도록 허용되어 있지 않으면, error를 반환한다.

      10. permissionStatepermissionNameglobal이 주어졌을 때 현재 권한 상태 가져오기의 결과로 둔다.

      11. permissionStatedenied이면 error를 반환한다.

      12. permissionStategranted이면 null을 반환한다.

      13. global에 대해 permissionName을 부여할지 여부를 사용자가 선택하도록 프롬프트한다:

        1. 사용자가 권한을 부여하면 null을 반환한다.

        2. 사용자가 권한을 거부하면 error를 반환한다.

    6. null을 반환한다.

  6. fetch 알고리즘은 requestpolicy container가 설정된 직후에 2개의 새 단계를 추가하도록 수정된다:

    1. requesttarget IP address space가 null이면:

      1. requestURLhost hostIP 주소이고, host에 대해 IP 주소 공간을 결정 알고리즘을 실행한 결과가 local이면, requesttarget IP address spacelocal로 설정한다.

      2. requestURLhostpublic suffix"local"이면, requesttarget IP address spacelocal로 설정한다.

        NOTE: 요청의 URL의 host가 “localhost” 또는 “127.0.0.1”인 경우에도 target IP address space를 local로 설정할 수 있다 ([LET-LOCALHOST-BE-LOCALHOST] 때문에). 그러나 loopback 사례는 이미 잠재적으로 신뢰할 수 있는 것으로 간주되어 혼합 콘텐츠 검사를 트리거하지 않으므로 별도의 처리가 필요하지 않다.

        NOTE: 명시적 targetAddressSpace가 fetch() API에 의해 설정된 경우 이를 선호하기 위해, 이미 null이 아닌 경우 여기서 target IP address space를 설정하지 않는다.

  7. HTTP-network fetch 알고리즘은 새로 획득한 connection이 failure가 아님을 검사한 직후에 3개의 새 단계를 추가하도록 수정된다:

    1. responseIP addressconnectionIP address로 설정한다.

    2. localNetworkAccessCheckResultfetchParamsrequestconnectionIP address에 대해 Local Network Access check를 실행한 결과로 둔다.

    3. localNetworkAccessCheckResultnetwork error이면, localNetworkAccessCheckResult를 반환한다.

  8. HTTP-network-or-cache fetch 알고리즘은 9단계 직후에 새 단계를 추가하도록 수정된다:

    1. response가 null이 아니면:

      1. localNetworkAccessCheckResultrequestresponseIP address에 대해 Local Network Access check를 실행한 결과로 둔다.

      2. localNetworkAccessCheckResultnetwork error이면, localNetworkAccessCheckResult를 반환한다.

NOTE: 로컬 네트워크 요청이 보안 컨텍스트에서 만들어져야 한다는 요구사항은, 요청이 로컬 네트워크 요청으로 간주될 수 있음을 사전에 알 수 없는 한, 모든 안전하지 않은 요청이 혼합 콘텐츠로 차단됨을 의미한다. target IP address space 속성(위 6i 및 6ii 단계 참조)을 설정함으로써 Mixed Content에는 작은 변경만 필요하다. § 3.2 Mixed Content와의 통합을 참조하라.

3.1.2. Fetch API

Fetch API도 조정되어야 한다.

3.2. Mixed Content와의 통합

Should fetching request be blocked as mixed content?allowed 조건 중 하나에 다음 조건을 추가하도록 수정된다:

  1. requestorigin잠재적으로 신뢰할 수 있는 출처가 아니고, requesttarget IP address spacelocal이다.

"Upgrade request to an a priori authenticated URL as mixed content, if appropriate" 알고리즘은 1단계에서 업그레이드 예외로 다음 조건을 추가하도록 수정된다:

  1. requesttarget IP address spacelocal이다

3.3. WebSockets와의 통합

WebSockets 연결은 동일한 로컬 네트워크 접근 권한 요구사항의 대상이 되어야 한다. WebSocket opening handshake는 11단계에서 fetch를 직접 적용하므로, 위에서 제안한 fetch 변경 외에는 WebSocket 명세에 필요한 수정이 없다.

Fetch API와 WebSockets API의 작은 차이 하나는 WebSockets에는 fetch의 RequestInit에 해당하는 것이 없으므로, ws:// URL에 대해 혼합 콘텐츠 검사를 우회하는 targetAddressSpace 옵션을 넣을 곳이 없다는 것이다.

3.4. WebTransport와의 통합

WebTransport 연결은 동일한 로컬 네트워크 접근 권한 요구사항의 대상이 되어야 한다.

WebTransport 명세에는 수정이 필요하지 않다. WebTransport 명세에서 WebTransport 연결 획득은 6단계에서 연결을 획득하기 위해 Fetch 명세를 참조하며, 이는 § 3.1.1 페칭에서 수정되고 있다

3.5. HTML과의 통합

[FETCH]의 검사를 지원하기 위해, 사용자 에이전트는 네트워크 요청이 만들어지는 컨텍스트의 소스 IP 주소 공간을 기억해야 한다. 이를 위해 [HTML] 명세는 다음과 같이 패치된다:

  1. IP 주소 공간 속성이 policy container struct에 추가된다.

    1. 초기값은 public이다.

  2. clone a policy container 알고리즘에 추가 단계가 추가된다:

    1. cloneIP 주소 공간policyContainerIP 주소 공간으로 설정한다.

  3. create a policy container from a fetch response 알고리즘에 추가 단계가 추가된다:

    1. resultIP 주소 공간responseIP address에 대해 IP 주소 공간을 결정 알고리즘을 실행한 결과로 설정한다.

example.com공개 주소(예: 123.123.123.123)로 해석된다고 가정하면, 그러면 Documenthttps://example.com/document.html로 이동할 때 생성되며, 그 정책 컨테이너IP 주소 공간 속성이 public으로 설정된다.

그런 다음 이 Documentabout:srcdoc iframe을 포함하면, 그러면 자식 프레임의 Document는 그 정책 컨테이너IP 주소 공간 속성이 public으로 설정된다.

반면에, example.com로컬 주소 (예: 127.0.0.1)로 해석된다면, 그러면 Documenthttps://example.com/document.html로 이동할 때 생성되며, 그 정책 컨테이너IP 주소 공간 속성이 local로 설정된다.

TODO: 또한 HTML § 7.1.4 Cross-origin embedder policies의 Private Network Access 참조를 갱신한다.

3.6. Workers와의 통합

이 절은 비규범적이다.

WorkerGlobalScope는 이미 policy container 필드를 가지며, 이는 create a policy container from a fetch response 알고리즘을 사용해 채워지므로, 위의 Fetch 및 HTML과의 통합은 문서 컨텍스트와 마찬가지로 worker 컨텍스트에도 적용된다.

example.com공개 주소(예: 123.123.123.123)로 해석된다고 가정하면, 그러면 WorkerGlobalScopehttps://example.com/worker.js에서 스크립트를 가져와 생성되며, 그 정책 컨테이너IP 주소 공간 속성이 public으로 설정된다.

이 워커가 시작한 모든 fetch 요청연결을 얻는 대상 IP 주소가 local 또는 loopback 주소 공간에 있다면, 이후 로컬 네트워크 요청이 된다.

Chromium의 구현은 현재 service worker가 시작한 fetch에 대해 worker의 스크립트 출처를 기반으로 LNA 권한을 적용한다(service worker가 실행 중일 때 활성 document가 주변에 없을 수 있기 때문이다). 이는 worker의 partitioned storage key를 기반으로 하는 것이 더 나을 수 있으며, permissions policy가 service worker를 지원하면 좋을 것이다.

Service Worker soft update 알고리즘은 갱신된 스크립트를 fetching할 때 안타깝게도 request client를 "null"로 설정한다. 이는 여러 문제를 일으키며, 위에서 제시한 로컬 네트워크 접근 검사 알고리즘을 방해한다. 실제로 fetch 중에 policy container를 복사해 올 request client가 없다. wicg/private-network-access issue #83을 참조하라.

4. 구현 고려 사항

4.1. File URL

file URL이 위에서 설명한 public/local 체계에 어떻게 들어맞는지는 완전히 명확하지 않다. 한편으로는 사람들이 악의적인 HTML 파일을 로컬에서 열어 스스로를 해치지 않도록 막는 것이 좋겠지만, 다른 한편으로는 로컬에서 실행되는 코드는 어느 정도 일관된 위협 모델 밖에 있다.

현재로서는 file URL을 local로 취급하는 쪽으로 보수적으로 판단하자. 이들은 루프백 주소의 어떤 것만큼이나 로컬 시스템의 일부로 보이기 때문이다.

구현 경험 후 이를 재평가하라.

4.2. 프록시

Chromium의 이 명세 현재 구현에서 프록시는 프록시하는 리소스의 주소 공간에 영향을 준다. 구체적으로, 프록시를 통해 fetch된 리소스는 프록시 자체의 IP 주소에서 fetch된 것으로 간주된다.

public 주소의 foo.example이 제공하는 Document가 로컬 주소의 프록시를 통해 사용자 에이전트에 의해 fetch되면, 그 Documentpolicy containerIP 주소 공간은 local로 설정된다.

Document는 이어서 브라우저가 접근 가능한 다른 로컬 주소로 요청을 만들 수 있게 된다.

이는 웹사이트가 로컬 주소로 요청을 만들 수 있음을 관찰하여 자신이 프록시되었음을 알 수 있게 하며, 이는 개인정보 정보 유출이다. 이는 로컬 네트워크에 있는 리소스의 URL을 정확히 추측해야 하지만, 한 번의 올바른 추측만으로 충분하다.

이는 비교적 드물 것으로 예상되며 더 많은 완화를 정당화하지 않는다. 결국 현재 상태에서는 모든 웹사이트가 아무 제한 없이 모든 IP 주소로 요청을 만들 수 있다.

프록시가 브라우저에 "이 리소스를 어쨌든 public/local로 취급해 달라"고 말할 수 있는 메커니즘을 살펴보는 것은 흥미로울 것이다. 이를 통해 프록시 뒤의 IP 주소에 대한 일부 정보를 전달할 수 있다.

4.3. HTTP 캐시

HTTP 캐시의 응답은 위 § 3.1 Fetch와의 통합에 명시된 대로 Local Network Access 검사의 대상이다. 아래에는 캐시에서 어떤 종류의 리소스가 로드되는지에 따라 이러한 검사가 실제로 어떻게 작동하는지에 대한 몇 가지 추가 세부 사항(및 예제)이 있다.

4.3.1. 메인 리소스

캐시된 response에서 구성된 document는 해당 response가 처음 로드된 IP 주소를 기억한다. document의 IP 주소 공간은 IP 주소에서 새로 파생된다.

일반적인 경우, 이는 documentpolicy container의 IP 주소 공간이 변경 없이 복원됨을 의미한다. 그러나 사용자 에이전트의 구성이 변경된 경우, 파생된 IP 주소 공간은 달라질 수 있다.

사용자 에이전트는 http://foo.example/로 탐색하여 1.2.3.4에서 메인 리소스를 로드하고 이를 캐시한 뒤, 결과 documentpolicy container의 IP 주소 공간을 public으로 설정한다.

그 후 사용자 에이전트가 다시 시작되고, 1.2.3.4를 local 주소로 분류해야 한다고 지정하는 새 구성이 적용된다.

사용자 에이전트는 다시 http://foo.example/로 탐색하여 HTTP 캐시에서 메인 리소스를 로드한다. 결과 documentpolicy container의 IP 주소 공간은 이제 local로 설정된다.

4.3.2. 하위 리소스

메인 리소스와 마찬가지로, 캐시된 응답에서 구성된 하위 리소스는 응답이 처음 로드된 IP 주소를 기억한다. 응답의 IP 주소 공간은 IP 주소에서 새로 파생된다.

일반적인 경우, 이는 응답의 IP 주소 공간이 변경 없이 복원됨을 의미한다. 그러나 사용자 에이전트의 구성이 변경된 경우, 파생된 IP 주소 공간은 달라질 수 있다.

하위 리소스 요청이 LNA 검사로 차단되면(즉, 권한이 거부되면), 캐시되는 리소스 응답은 없다. 나중에 권한이 재설정되거나 부여되면, 하위 리소스 요청은 네트워크로 간다.

이전에 허용된 하위 리소스 로드

사용자 에이전트는 https://foo.example로 탐색하며, 이는 1.2.3.4에서 로드된다(그 IP 주소 공간은 public). 문서는 http://bar.local/image.jpg에 대한 하위 리소스 요청을 트리거하고, 연결이 생성될 때 그 IP 주소는 10.0.1.1이다(그 IP 주소 공간은 local). 이는 권한 프롬프트를 트리거하여 https://foo.example에 Local Network Access 권한을 부여하고, 그 후 하위 리소스가 로드되어 사용자 에이전트의 캐시에 추가된다.

사용자 에이전트는 https://foo.example에 대한 권한을 재설정한다.

사용자 에이전트는 다시 https://foo.example로 탐색하고, 이는 다시 http://bar.local/image.jpeg에 대한 하위 리소스 요청을 트리거한다. 이 리소스는 사용자 에이전트의 캐시에 있으며, 캐시된 응답 IP 주소는 10.0.1.1이다. 이는 다시 권한 프롬프트를 트리거하고, 부여되면 사용자 에이전트의 캐시에서 리소스 로드를 완료한다.

이전에 차단된 하위 리소스 로드

사용자 에이전트는 https://foo.example로 탐색하며, 이는 1.2.3.4에서 로드된다(그 IP 주소 공간은 public). 문서는 http://bar.local/image.jpg에 대한 하위 리소스 요청을 트리거하고, 연결이 생성될 때 그 IP 주소는 10.0.1.1이다(그 IP 주소 공간은 local). 이는 권한 프롬프트를 트리거하여 https://foo.example에 Local Network Access 권한을 거부한다. 하위 리소스 요청은 차단되고 사용자 에이전트의 캐시에 리소스가 추가되지 않는다.

사용자 에이전트는 https://foo.example에 대한 권한을 재설정한다.

사용자 에이전트는 다시 https://foo.example로 탐색하고, 이는 다시 http://bar.local/image.jpeg에 대한 하위 리소스 요청을 트리거한다. 이 리소스는 사용자 에이전트의 캐시에 없으므로, HTTP network fetch를 거치고 권한 프롬프트를 트리거한다.

보안 영향에 대한 논의는 § 5.6 HTTP 캐시를 참조하라.

4.4. 출시 어려움

Local Network Access는 본질적으로 로컬 네트워크에 대한 직접 접근을 더 안전한 사용자 에이전트 매개 대안으로 대체하기 위해 폐기한다. 웹 폐기는 어렵다. Chromium은 이전에 이 명세의 전신인 [PRIVATE-NETWORK-ACCESS]의 일부를 출시하는 과정에서 많은 걸림돌을 만났다.

특히 로컬 IP 주소 공간의 비보안 컨텍스트에서 localhost의 서비스로 향하는 fetch에 제한을 적용하는 것은 보상이 더 낮은 데 비해 특히 어려운 것으로 드러났다. 실제로 이러한 fetch를 악용하려면 공격자가 이미 사설 네트워크에 발판을 가지고 있어야 하며, 이는 공격 난이도를 상당히 높인다. 그 결과 Chromium은 이러한 fetch를 일시적으로 제한에서 제외하고, public IP 주소 공간에서의 fetch에 집중하기로 선택했다. 보안 영향에 대한 논의는 § 5.5 로컬 네트워크 공격자를 참조하라.

5. 보안 및 개인정보 보호 고려 사항

5.1. 사용자 중재

이 문서의 제안은 사용자가 public 인터넷으로부터의 접근에 동의함을 보장할 뿐이다. 이 제안은 기기가 public 인터넷으로부터의 연결을 명시적으로 승인할 수 있도록 허용하지 않는다.

기기가 public 인터넷으로부터의 연결을 명시적으로 승인해야 하는 대안 모델은 [PRIVATE-NETWORK-ACCESS]에서 시도되었지만, 출시 어려움에 부딪혔다.

대상 엔드포인트가 연결에 opt in하는지 여부와 관계없이 사용자 중재를 요구하는 것은, 로컬 엔드포인트와 원격 웹사이트가 결탁하여 사용자 신원을 연결하는 "Local Mess" 추적 방법과 같은 개인정보 문제를 완화하는 데도 도움이 된다.

5.2. DNS 리바인딩

여기서 설명하는 완화는 사용자 에이전트가 특정 리소스를 로드할 때 실제로 연결하는 IP 주소에 대해 작동한다. 이 검사는 만들어지는 각 새 연결마다 수행되어야 한다. 그렇지 않으면 DNS 리바인딩 공격이 사용자 에이전트를 속여 드러내서는 안 되는 정보를 드러내게 할 수 있다.

DNS 리바인딩 공격은 또한 로컬 네트워크 접근 검사가 모든 public에서 local로 향하는 요청에 적용되어야 함을 의미한다 (즉, 알고리즘을 “local 엔드포인트에 대한 모든 교차 출처 요청”으로 단순화할 수 없다. 이는 사용자가 a.example로 탐색한 뒤 네트워크가 바뀌거나 DNS가 변경되어 a.example이 로컬 주소를 가리키게 만드는 위험을 열기 때문이다).

5.3. 완화 범위

이 문서의 제안은 로컬 웹 서비스에 대한 공격을 완화할 뿐이며, 이를 완전히 해결할 수는 없다. 예를 들어, 라우터의 웹 기반 관리 인터페이스는 자체적으로 CSRF를 방어하도록 설계되고 구현되어야 하며, 이 문서에 명시된 대로 동작하는 UA에 의존해서는 안 된다. 이 문서가 명시하는 완화는 오늘날 로컬 웹 서비스 구현 품질의 현실을 고려할 때 필요하지만, 모든 UA가 이 완화를 구현하더라도 벤더는 자신의 책임이 면제되었다고 생각해서는 안 된다.

5.4. 교차 네트워크 혼동

대부분의 로컬 네트워크는 서로 통신할 수 없지만, 이 명세는 그것들을 모두 local IP 주소 공간에 속하는 것으로 취급한다. 더 나아가, 로컬 주소는 사용되는 로컬 네트워크에서만 의미가 있다. 같은 IP 주소가 서로 다른 두 네트워크에서 완전히 다른 기기를 가리킬 수 있다. 사용자가 a.example에 로컬 네트워크 요청을 만들 권한을 부여한 뒤 다른 네트워크로 이동하면, a.example은 계속 로컬 네트워크 요청을 만들 수 있게 된다.

이는 교차 네트워크 공격의 문을 연다:

이 공격들은 새로운 것이 아니며, 단지 이 명세의 한계를 보여주는 예일 뿐이다.

잠재적 완화는 네트워크 변경을 감지하고 이전 네트워크에 특정된 상태를 지우는 것을 요구할 것이다. 이를 완전히 일반적인 방식으로 수행하는 것은 모든 상태를 지우는 것 외에는 불가능할 가능성이 높다. 실용적인 절충점을 찾을 수 있을지도 모른다. wicg/private-network-access issue #28을 참조하라.

대안적 접근은 서로 다른 네트워크를 구별하는 식별자에 권한 부여의 범위를 한정하는 것일 수 있다.

5.5. 로컬 네트워크 공격자

로컬 네트워크 접근 검사가 local 주소 공간으로 향하는 모든 교차 출처 요청에 적용될 때까지는, 로컬 네트워크의 악의적 서버가 (1) 로컬 네트워크의 다른 서버를 공격하고, (2) 사용자의 머신에서 localhost로 실행되는 서비스를 공격할 수 있다. (1)은 사용자의 브라우저를 악용하지 않고도 이미 가능하지만, (2)는 여전히 우려 사항이다. 예를 들어, captive portal은 사용자를 악의적인 페이지로 리디렉션하여, 이 페이지가 사용자의 머신에서 실행 중인 취약한 localhost 서비스를 탐색하고 공격하려고 시도하게 할 수 있다. (wicg/private-network-accesss issue #39도 참조하라.)

우리는 drive-by 웹의 public 웹사이트를 더 시급한 보안(및 개인정보) 위험으로 보고, 로컬 네트워크 공격자로부터 남아 있는 위험에도 불구하고 이러한 보호의 점진적 출시가 가치 있는 진전이라고 본다.

5.6. HTTP 캐시

5.6.1. 하위 리소스에 검사 적용

캐시된 하위 리소스는 이 명세에 의해 보호된다. HTTP 캐시가 소스 IP 주소를 기억하고, 이를 HTTP-network-or-cache fetch 중 Local Network Access check 알고리즘에서 사용할 수 있기 때문이다.

이 검사가 없으면, 악의적인 public 웹사이트가 사용자가 과거에 특정한 private 웹사이트를 방문했는지 판단할 수 있을 것이다.

HTTP 캐시 파티셔닝 때문에, 하위 리소스는 공격자가 캐시 항목의 network partition key를 복제하는 데 성공한 경우에만 캐시에서 로드될 수 있다. 공격자가 이를 달성할 수 있는 한 가지 방법은 DNS를 조작하여(처음 캐시된 리소스를 포함했던 최상위 사이트를 가장하기 위해 § 5.2 DNS 리바인딩도 참조) 캐시 항목의 network partition key를 복제하는 것이다.

사용자 에이전트는 http://router.example로 탐색하며, 이는 192.168.1.1에서 제공된다. 웹사이트는 http://router.example/$BRAND-logo.png의 로고를 포함하고, 이는 캐시된다.

그 후 악의적인 공격자가 router.example을 공격자가 제어하는 public IP 주소로 리바인딩하고, 어떻게든 사용자가 다시 http://router.example을 방문하도록 속인다. 악의적인 웹사이트는 로고를 포함하려고 시도하고, 로드가 성공하는지 감시한다. 성공하면 공격자는 사용자의 라우터 브랜드를 알아낸 것이다.

5.6.2. HTTP 캐시 포이즈닝

이 명세는 로컬 네트워크 서버가 public 웹사이트로부터 요청을 받는 것을 보호하는 것을 목표로 하지만, DNS 리바인딩은 인증되지 않은 리소스의 캐시 포이즈닝을 통해 유사한 공격을 수행하는 데 사용될 수 있다.

http://router.com으로 가장한 공격자는 악의적인 스크립트를 http://router.com/totally-legit.js에 캐시할 수 있다. 나중에 사용자가 http://router.com/으로 탐색하면, 페이지는 포이즈닝된 스크립트를 요청하여 공격자 코드를 덜 공용 IP 주소 공간에서 실행할 수 있다.

이 공격은 캐시 파티셔닝으로 부분적으로 완화된다. 캐시 파티셔닝은 공격자가 리소스를 캐싱하기 전에 최상위 탐색 컨텍스트를 http://router.com/으로 탐색해야 하게 만들며, 이는 은밀하지 않다. 또한 이는 Local Network Access에 특화된 것이 아니라, 평문 HTTP의 인증 및 무결성 보호 부족의 증상이다.

6. 감사의 말

원래의 Private Network Access 제안 및 명세 작업을 수행했으며, 자신의 작업을 아낌없이 논의하고 앞으로의 경로를 브레인스토밍하는 데 도움을 준 Titouan Rigoudy, Jonathan Hao, Yifan Luo의 귀중한 피드백과 조언에 깊이 감사한다.

적합성

문서 관례

적합성 요구사항은 서술적 단언과 RFC 2119 용어의 조합으로 표현된다. 이 문서의 규범적 부분에서 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”은 RFC 2119에 설명된 대로 해석되어야 한다. 그러나 가독성을 위해, 이 명세에서 이러한 단어가 모두 대문자로 표시되지는 않는다.

명시적으로 비규범적이라고 표시된 절, 예제 및 note를 제외하고 이 명세의 모든 텍스트는 규범적이다. [RFC2119]

이 명세의 예제는 “for example”이라는 단어로 소개되거나 다음과 같이 class="example"을 사용하여 규범적 텍스트와 구분된다:

이것은 정보 제공용 예제의 예이다.

정보 제공용 note는 “Note”라는 단어로 시작하며 다음과 같이 class="note"를 사용하여 규범적 텍스트와 구분된다:

Note, 이것은 정보 제공용 note이다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같은 “Tests” 블록에 문서화될 수 있다. 이러한 블록은 비규범적이다.


색인

이 명세에서 정의하는 용어

참조에서 정의하는 용어

참고 문헌

규범적 참고 문헌

[CSP3]
Mike West; Antonio Sartori. 콘텐츠 보안 정책 레벨 3. URL: https://w3c.github.io/webappsec-csp/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MIXED-CONTENT]
Emily Stark; Mike West; Carlos IbarraLopez. Mixed Content. URL: https://w3c.github.io/webappsec-mixed-content/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. URL: https://w3c.github.io/permissions/
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy. URL: https://w3c.github.io/webappsec-permissions-policy/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SECURE-CONTEXTS]
Mike West. Secure Contexts. URL: https://w3c.github.io/webappsec-secure-contexts/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

비규범적 참고 문헌

[AVASTIUM]
Avast: A web-accessible RPC endpoint can launch 'SafeZone' (also called Avastium), a Chromium fork with critical security checks removed.. URL: https://bugs.chromium.org/p/project-zero/issues/detail?id=679
[CSRF-EXPLOIT-KIT]
Kafeine. An Exploit Kit dedicated to CSRF Pharming. URL: http://malware.dontneedcoffee.com/2015/05/an-exploit-kit-dedicated-to-csrf.html
[DRIVE-BY-PHARMING]
Sid Stamm; Zulfikar Ramzan; Markus Jakobsson. Drive-By Pharming. URL: https://link.springer.com/chapter/10.1007/978-3-540-77048-0_38
[IPV4-REGISTRY]
IANA IPv4 Special-Purpose Address Registry. URL: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
[IPV6-REGISTRY]
IANA IPv6 Special-Purpose Address Registry. URL: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
[LET-LOCALHOST-BE-LOCALHOST]
Let 'localhost' be localhost.. URL: https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-let-localhost-be-localhost
[PRIVATE-NETWORK-ACCESS]
Private Network Access. Draft Community Group Report. URL: https://wicg.github.io/private-network-access/
[RFC1122]
R. Braden, Ed.. Requirements for Internet Hosts - Communication Layers. 1989년 10월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc1122
[RFC1884]
R. Hinden, Ed.; S. Deering, Ed.. IP Version 6 Addressing Architecture. 1995년 12월. Historic. URL: https://www.rfc-editor.org/rfc/rfc1884
[RFC1918]
Y. Rekhter; et al. Address Allocation for Private Internets. 1996년 2월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc1918
[RFC2544]
S. Bradner; J. McQuaid. Benchmarking Methodology for Network Interconnect Devices. 1999년 3월. Informational. URL: https://www.rfc-editor.org/rfc/rfc2544
[RFC3513]
R. Hinden; S. Deering. Internet Protocol Version 6 (IPv6) Addressing Architecture. 2003년 4월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3513
[RFC3849]
G. Huston; A. Lord; P. Smith. IPv6 Address Prefix Reserved for Documentation. 2004년 7월. Informational. URL: https://www.rfc-editor.org/rfc/rfc3849
[RFC3927]
S. Cheshire; B. Aboba; E. Guttman. Dynamic Configuration of IPv4 Link-Local Addresses. 2005년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3927
[RFC4193]
R. Hinden; B. Haberman. Unique Local IPv6 Unicast Addresses. 2005년 10월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4193
[RFC4291]
R. Hinden; S. Deering. IP Version 6 Addressing Architecture. 2006년 2월. Draft Standard. URL: https://www.rfc-editor.org/rfc/rfc4291
[RFC5735]
M. Cotton; L. Vegoda. Special Use IPv4 Addresses. 2010년 1월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc5735
[RFC6555]
D. Wing; A. Yourtchenko. Happy Eyeballs: Success with Dual-Stack Hosts. 2012년 4월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6555
[RFC6598]
J. Weil; et al. IANA-Reserved IPv4 Prefix for Shared Address Space. 2012년 4월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc6598
[RFC8305]
D. Schinazi; T. Pauly. Happy Eyeballs Version 2: Better Connectivity Using Concurrency. 2017년 12월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8305
[RFC9637]
G. Huston; N. Buraglio. Expanding the IPv6 Documentation Space. 2024년 8월. Informational. URL: https://www.rfc-editor.org/rfc/rfc9637
[SOHO-PHARMING]
Team Cymru. SOHO Pharming. URL: https://331.cybersec.fun/TeamCymruSOHOPharming.pdf
[TREND-MICRO]
TrendMicro node.js HTTP server listening on localhost can execute commands. URL: https://bugs.chromium.org/p/project-zero/issues/detail?id=693

IDL 색인

enum IPAddressSpace { "public", "local", "loopback" };

partial dictionary RequestInit {
  IPAddressSpace targetAddressSpace;
};

partial interface Request {
  readonly attribute IPAddressSpace targetAddressSpace;
};

이슈 색인

로컬 네트워크 요청의 정의는 current urlhost가 IP 주소로 매핑되고, 그 IP 주소 공간public이 아닌 모든 교차 출처 요청을 포괄하도록 확장될 수 있다. 이는 로컬 네트워크의 악의적 서버가 localhost의 서버를 포함한 다른 서버를 공격하는 것을 방지할 것이다. wicg/private-network-access issue #39를 참조하라.
향후 모든 교차 출처 local 요청에 LNA 검사를 적용할 수 있도록(위 이슈 참조), Chromium은 현재 공개적으로 신뢰되는 HTTPS 인증서를 얻기 어려울 가능성이 큰 로컬 서버(예: .local의 서버와 사설 IP 리터럴)를 이 요구사항에서 제외할 계획이다. 더 많은 논의는 § 4.4 출시 어려움을 참조하고, 또한 wicg/private-network-access issue #96도 참조하라.
Chromium은 현재 비표준 CSP 지시어 treat-as-public-address를 지원한다 (private-network-access#csp 참조). wicg/private-network-access issue #39가 구현되면 이 지시어는 불필요해질 것이다.
https://github.com/WICG/private-network-access/issues/88 은 이를 CSP 지시문에서 다른 위치로 옮길 것을 권고했다.
Chromium은 현재 LNA 제한을 iframe 탐색에만 적용한다. 이를 메인 프레임 탐색(특히 opener에 의해 제어될 수 있는 팝업 창)까지 확장할 가치가 있을 수 있다.
wicg/local-network-access issue #103를 해결하려면, 대신 출처를 해석한 뒤 실제 연결을 만들기 전에 검사를 수행하도록 obtain a connection의 4.6단계에 통합해야 한다.
Service Worker의 로컬 네트워크 접근 동작을 정의하라.
Chromium의 구현은 현재 service worker가 시작한 fetch에 대해 worker의 스크립트 출처를 기반으로 LNA 권한을 적용한다(service worker가 실행 중일 때 활성 document가 주변에 없을 수 있기 때문이다). 이는 worker의 partitioned storage key를 기반으로 하는 것이 더 나을 수 있으며, permissions policy가 service workers를 지원하면 좋을 것이다.
Service Worker soft update 알고리즘은 갱신된 스크립트를 fetching할 때 안타깝게도 request client를 "null"로 설정한다. 이는 여러 문제를 일으키며, 위에서 제시한 로컬 네트워크 접근 검사 알고리즘을 방해한다. 실제로 request client가 없어, fetch 중에 policy container를 복사할 수 없다. wicg/private-network-access issue #83을 참조하라.
구현 경험 후 이를 재평가하라.
잠재적 완화는 네트워크 변경을 감지하고 이전 네트워크에 특정된 상태를 지우는 것을 요구할 것이다. 이를 완전히 일반적인 방식으로 수행하는 것은 모든 상태를 지우는 것 외에는 불가능할 가능성이 높다. 실용적인 절충점을 찾을 수 있을지도 모른다. wicg/private-network-access issue #28을 참조하라.