로컬 네트워크 액세스

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

이 문서에 대한 자세한 정보
이 버전:
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 주소 공간에 속하지 않으면 요청은 실패한다. 속한다면, 권한을 검사하여 요청을 허용하거나 실패시킬 수 있다.

2.6. 권한

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

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

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. 연결 객체에는 값이 null이거나 IP 주소인 새로운 IP 주소 속성이 주어지며, 초깃값은 null이다.

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

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

  3. 요청 객체에는 새로운 대상 IP 주소 공간 속성이 주어지며, 초깃값은 null이다.

  4. 응답 객체에는 값이 null이거나 IP 주소인 새로운 IP 주소 속성이 주어지며, 초깃값은 null이다.

  5. 새로운 로컬 네트워크 액세스 검사 알고리즘을 정의한다. 요청 requestIP 주소 address가 주어졌을 때:

    참고: 이 알고리즘은 IP 주소를 받으므로 HTTP 네트워크 가져오기(여기서는 연결이 있음) 또는 HTTP 네트워크 또는 캐시 가져오기(여기서는 저장된 응답에 저장된 IP 주소가 있음)에서 호출할 수 있다. 매핑은 사용자 에이전트에 의해 동적으로 갱신될 수 있으므로, 이는 의도적으로 매번 IP 주소 공간을 다시 계산한다.

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

    2. request출처잠재적으로 신뢰할 수 있는 출처이고 request현재 URL출처request출처동일 출처이면 null을 반환한다.

    3. request정책 컨테이너가 null이면 null을 반환한다.

      참고: request정책 컨테이너가 null이면 LNA 검사는 request에 적용되지 않는다. 가져오기 알고리즘의 사용자는 request클라이언트를 null이 아닌 환경 설정 객체로 설정하고, 해당 객체가 null이 아닌 정책 컨테이너를 갖도록 한 뒤 가져오기가 그에 따라 request정책 컨테이너를 초기화하도록 하거나, request정책 컨테이너를 null이 아닌 값으로 직접 설정하도록 주의해야 한다.

    4. request대상 IP 주소 공간이 null이 아니면:

      1. 단언: request대상 IP 주소 공간공개가 아니다.

      2. addressSpace가 같지 않다면 request대상 IP 주소 공간과 같지 않으면 네트워크 오류를 반환한다.

      3. null을 반환한다.

    5. addressSpacerequest정책 컨테이너IP 주소 공간보다 덜 공개적이면:

      1. error네트워크 오류로 설정한다.

      2. request클라이언트보안 컨텍스트가 아니면 (null인 경우 포함) error를 반환한다.

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

      4. addressSpace로컬이면 permissionName을 "local-network"로 설정하고, addressSpace루프백이면 "loopback-network"로 설정한다.

      5. settingsObjectrequest클라이언트로 설정한다.

      6. globalsettingsObject전역 객체로 설정한다.

      7. documentglobal연결된 Document로 설정한다.

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

        참고: Service Worker에는 항상 연결된 Document가 있는 것은 아니므로, 이 단계는 Service Worker의 로컬 네트워크 요청이 실패하도록 한다. 이 명세의 향후 버전에서는 Worker에서 Permissions Policy가 아직 지원되지 않는다는 점을 특히 고려하여 Worker를 처리하는 방법을 정의해야 한다. 다음을 참조하라. w3c/webappsec-permissions-policy#207.

        Service Worker의 로컬 네트워크 액세스 동작을 정의한다.

      9. documentpermissionName사용하도록 허용되지 않았으면 error를 반환한다.

      10. permissionStatepermissionNameglobal이 주어졌을 때 현재 권한 상태를 가져온 결과로 설정한다.

      11. permissionState거부됨이면 error를 반환한다.

      12. permissionState허용됨이면 null을 반환한다.

      13. global에 대해 permissionName을 허용할지 여부를 사용자에게 선택하도록 요청한다:

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

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

    6. null을 반환한다.

  6. 가져오기 알고리즘은 request정책 컨테이너가 설정된 직후 새로운 2개 단계를 추가하도록 수정된다:

    1. request대상 IP 주소 공간이 null이면:

      1. requestURL호스트 hostIP 주소이고 host에 대해 IP 주소 공간 결정 알고리즘을 실행한 결과가 로컬이면, request대상 IP 주소 공간로컬로 설정한다.

      2. requestURL호스트공개 접미사"local"이면, request대상 IP 주소 공간로컬로 설정한다.

        참고: 요청 URL의 호스트가 “localhost” 또는 “127.0.0.1”인 경우에도 ([LET-LOCALHOST-BE-LOCALHOST] 때문에) 대상 IP 주소 공간을 로컬로 설정할 수도 있지만, 루프백 사례는 이미 잠재적으로 신뢰할 수 있는 것으로 간주되어 혼합 콘텐츠 검사를 유발하지 않으므로 특별히 처리할 필요가 없다.

        참고: fetch() API에서 명시적인 targetAddressSpace가 설정된 경우 이를 우선하기 위해, 대상 IP 주소 공간이 이미 null이 아니면 여기서 설정하지 않는다.

  7. HTTP 네트워크 가져오기 알고리즘은 새로 얻은 connection이 실패가 아님을 확인한 직후 새로운 3개 단계를 추가하도록 수정된다:

    1. responseIP 주소connectionIP 주소로 설정한다.

    2. localNetworkAccessCheckResultfetchParams요청connectionIP 주소에 대해 로컬 네트워크 액세스 검사를 실행한 결과로 설정한다.

    3. localNetworkAccessCheckResult네트워크 오류이면 localNetworkAccessCheckResult를 반환한다.

  8. HTTP 네트워크 또는 캐시 가져오기 알고리즘은 9단계 직후에 새로운 단계를 추가하도록 수정된다:

    1. response가 null이 아니면:

      1. localNetworkAccessCheckResultrequestresponseIP 주소에 대해 로컬 네트워크 액세스 검사를 실행한 결과로 설정한다.

      2. localNetworkAccessCheckResult네트워크 오류이면 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)로 확인된다고 가정하면, https://example.com/document.html로 이동할 때 생성되는 Document정책 컨테이너IP 주소 공간 속성은 공개로 설정된다.

그런 다음 이 Documentabout:srcdoc iframe을 삽입하면, 자식 프레임의 Document정책 컨테이너IP 주소 공간 속성은 공개로 설정된다.

반면 example.com로컬 주소 (예: 127.0.0.1)로 확인되면, https://example.com/document.html로 이동할 때 생성되는 Document정책 컨테이너IP 주소 공간 속성은 로컬로 설정된다.

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)로 확인된다고 가정하면, https://example.com/worker.js에서 스크립트를 가져와 생성된 WorkerGlobalScope정책 컨테이너IP 주소 공간 속성은 공개로 설정된다.

이 워커가 시작한 모든 fetch 요청연결을 획득하여 로컬 또는 루프백 주소 공간의 IP 주소에 연결되면, 이는 로컬 네트워크 요청이 된다.

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-access 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” 블록에 문서화될 수 있다. 이러한 블록은 비규범적이다.


색인

이 명세에서 정의하는 용어

참조에서 정의하는 용어

참고 문헌

규범적 참고 문헌

[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: 웹에서 액세스할 수 있는 RPC 엔드포인트가 중요한 보안 검사가 제거된 Chromium 포크인 'SafeZone'(Avastium이라고도 함)을 실행할 수 있음.. URL: https://bugs.chromium.org/p/project-zero/issues/detail?id=679
[CSRF-EXPLOIT-KIT]
Kafeine. CSRF 파밍 전용 익스플로잇 키트. URL: http://malware.dontneedcoffee.com/2015/05/an-exploit-kit-dedicated-to-csrf.html
[DRIVE-BY-PHARMING]
Sid Stamm; Zulfikar Ramzan; Markus Jakobsson. 드라이브 바이 파밍. URL: https://link.springer.com/chapter/10.1007/978-3-540-77048-0_38
[IPV4-REGISTRY]
IANA IPv4 특수 목적 주소 레지스트리. URL: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
[IPV6-REGISTRY]
IANA IPv6 특수 목적 주소 레지스트리. URL: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
[LET-LOCALHOST-BE-LOCALHOST]
'localhost'를 localhost로 취급하기.. URL: https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-let-localhost-be-localhost
[PRIVATE-NETWORK-ACCESS]
프라이빗 네트워크 액세스. 커뮤니티 그룹 보고서 초안. URL: https://wicg.github.io/private-network-access/
[RFC1122]
R. Braden, 편집자. 인터넷 호스트 요구사항 - 통신 계층. 1989년 10월. 인터넷 표준. URL: https://www.rfc-editor.org/info/rfc1122/
[RFC1884]
R. Hinden, 편집자; S. Deering, 편집자. IP 버전 6 주소 지정 아키텍처. 1995년 12월. 역사적 문서. URL: https://www.rfc-editor.org/info/rfc1884/
[RFC1918]
Y. Rekhter; 외. 프라이빗 인터넷을 위한 주소 할당. 1996년 2월. 현행 모범 사례. URL: https://www.rfc-editor.org/info/rfc1918/
[RFC2544]
S. Bradner; J. McQuaid. 네트워크 상호 연결 장치의 벤치마킹 방법론. 1999년 3월. 정보 제공. URL: https://www.rfc-editor.org/info/rfc2544/
[RFC3513]
R. Hinden; S. Deering. 인터넷 프로토콜 버전 6 (IPv6) 주소 지정 아키텍처. 2003년 4월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc3513/
[RFC3849]
G. Huston; A. Lord; P. Smith. 문서화를 위해 예약된 IPv6 주소 접두사. 2004년 7월. 정보 제공. URL: https://www.rfc-editor.org/info/rfc3849/
[RFC3927]
S. Cheshire; B. Aboba; E. Guttman. IPv4 링크 로컬 주소의 동적 구성. 2005년 5월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc3927/
[RFC4193]
R. Hinden; B. Haberman. 고유 로컬 IPv6 유니캐스트 주소. 2005년 10월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc4193/
[RFC4291]
R. Hinden; S. Deering. IP 버전 6 주소 지정 아키텍처. 2006년 2월. 표준 초안. URL: https://www.rfc-editor.org/info/rfc4291/
[RFC5735]
M. Cotton; L. Vegoda. 특수 용도 IPv4 주소. 2010년 1월. 현행 모범 사례. URL: https://www.rfc-editor.org/info/rfc5735/
[RFC6555]
D. Wing; A. Yourtchenko. Happy Eyeballs: 듀얼 스택 호스트를 통한 성공. 2012년 4월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc6555/
[RFC6598]
J. Weil; 외. 공유 주소 공간을 위한 IANA 예약 IPv4 접두사. 2012년 4월. 현행 모범 사례. URL: https://www.rfc-editor.org/info/rfc6598/
[RFC8305]
D. Schinazi; T. Pauly. Happy Eyeballs 버전 2: 동시성을 사용한 더 나은 연결성. 2017년 12월. 제안 표준. URL: https://www.rfc-editor.org/info/rfc8305/
[RFC9637]
G. Huston; N. Buraglio. IPv6 문서화 공간 확장. 2024년 8월. 정보 제공. URL: https://www.rfc-editor.org/info/rfc9637/
[SOHO-PHARMING]
Team Cymru. SOHO 파밍. URL: https://331.cybersec.fun/TeamCymruSOHOPharming.pdf
[TREND-MICRO]
localhost에서 수신 대기 중인 TrendMicro node.js HTTP 서버가 명령을 실행할 수 있음. 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은 현재 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을 참조하라.