연결 허용 목록

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

이 버전:
https://wicg.github.io/connection-allowlists/
이슈 추적:
GitHub
사양 내 인라인
편집자:
Mike West (Google)

초록

Connection-Allowlist 메커니즘은 다른 서버와 통신할 수 있는 컨텍스트의 능력에 대한 제약 조건 집합을 위한 간결한 정책 언어와 전달 메커니즘을 제공합니다. 목표는 개발자가 명시적 유출 채널을 문제에 맞게 좁게 조정된 방식으로 종합적으로 완화할 수 있는 능력을 제공하는 것입니다.

이 문서의 상태

이 사양은 웹 플랫폼 인큐베이터 커뮤니티 그룹에서 발행했습니다. 이는 W3C 표준이 아니며 W3C 표준화 과정에도 포함되어 있지 않습니다. W3C 커뮤니티 기여자 라이선스 계약 (CLA)에 따라 제한적인 옵트아웃 및 기타 조건이 적용된다는 점에 유의하십시오. W3C 커뮤니티 및 비즈니스 그룹에 대해 자세히 알아보십시오.

1. 소개

개발자는 자신의 페이지 컨텍스트에 로드되는 리소스와 페이지가 요청을 보낼 수 있는 엔드포인트를 제어하기를 원합니다. 이러한 제어는 여러 목적에 필요하며, 여기에는 사용자 데이터가 사용자 에이전트를 통해 흐를 수 있는 방식을 제한하는 것(유출 공격 완화)과 사이트의 아키텍처 및 의존성에 대한 제어 보장이 포함됩니다.

Content Security Policy는 이러한 필요 중 일부를 다루지만, 가장 중요한 사용 사례에 필요한 것보다 더 세분화된 방식으로 이를 수행하며, CSP가 배포하는 다른 보호 기능 때문에 복잡해진 구문과 문법을 사용합니다. [CSP]

`Connection-Allowlist`는 CSP에서 한 걸음 물러나, 페이지가 Fetch 및 기타 웹 플랫폼 API(WebRTC, Web Transport, FedCM, Web Payments, DNS Prefetch 등)를 통해 시작할 수 있는 명시적 요청을 제어하는 단일 사용 사례에 초점을 맞춥니다. 그 목표는 단순하고 포괄적인 방식을 제공하는 것입니다.

NOTE: '\' line wrapping per RFC 8792

Connection-Allowlist: (response-origin "https://cdn.example" "https://*.example.:tld" \
                       "https://api.example:*"); report-to=ReportingAPIEndpoint

사용자가 탐색한 문서와 함께 전달되는 이 헤더는 해당 문서가 목록에 지정된 URL 패턴과 일치하는 엔드포인트로만 요청과 연결을 허용하도록 제한합니다. [URLPATTERN] 여기에는 문서가 전달된 출처, https://cdn.example, 끝에서 두 번째 DNS 레이블이 example인 모든 호스트의 모든 하위 도메인, 모든 포트의 https://api.example 등이 포함됩니다.

허용 목록과 일치하지 않는 엔드포인트에 연결하려는 시도는 차단되며, report-to 매개변수에 지정된 Reporting API [REPORTING] endpoint로 보고됩니다(그리고 별도의 Reporting-Endpoints 헤더를 통해 정의됩니다).

1.1. 위협 모델

이 제안은 의도적으로 작으며, 클라이언트 측 공격 및/또는 잘못된 구성 중 구체적이지만 유용한 틈새 영역을 대상으로 합니다:

1.2. Content Security Policy와의 중복

이 제안은 특정 컨텍스트 내에서 리소스 사용에 제한을 두는 Content Security Policy의 접근 방식, 특히 fetch directives와 많은 공통점을 가집니다. 그래도 몇 가지 이유로 살펴볼 가치가 있어 보입니다:

  1. CSP의 모델은 너무 세분화되어 있습니다. 민감한 컨텍스트에서 데이터가 유출될 위험을 완화하려는 개발자는 요청이 만들어지거나 연결이 설정될 수 있는 모든 가능한 방식을 빠짐없이 포괄하는 보호가 필요합니다. CSP가 요청을 서로 독립적으로 제어할 수 있는 유형으로 분류하는 방식은 이 문제에 접근하는 잘못된 방법입니다. 웹 폰트 요청을 통해 데이터가 누출되는 것은 이미지나 스크립트 요청을 통해 데이터가 누출되는 것만큼 나쁘기 때문입니다. 이러한 요청 유형을 구분하면, 단순히 관련 없는 질문들로 인해 합리적인 방어 설계 과정이 복잡해집니다.

  2. CSP의 구문은 충분히 세분화되어 있지 않습니다. CSP가 지원하는 host-source 문법은 응답과 함께 전달되는 매우 장황한 헤더로 이어집니다. 별도의 정책은 URLPattern 구문으로 전환할 기회를 제공하며, 이는 더 현대적이고 유연하며 표준화된 매칭 구문을 제공함으로써 CSP 접근 방식에 대해 사람들이 제기해 온 일부 불만을 해결할 것입니다.

  3. CSP의 적용 범위는 불완전합니다. CSP는 Fetch를 통해 실행되는 HTTP 요청을 잘 다루지만, 웹 플랫폼 API가 연결을 설정할 수 있게 하는 수많은 방식을 빠짐없이 다루지는 않습니다. DNS prefetch와 WebRTC는 시작하기 좋은 예이며, 그 외에도 CSP의 위협 모델에 정확히 어떻게 들어맞는지 어려움을 겪어 온 많은 것들이 있습니다. 좁은 초점과 개발자에게 명시적인 약속을 갖는 새 정책을 만들면, 이러한 논의에는 방어 가능한 답과 사양 작성자에게 분명한 지침이 생길 것입니다.

2. 연결 허용 목록

Connection Allowlist는 주어진 컨텍스트가 연결할 수 있도록 허용된 URL 패턴 집합을 나타냅니다. 이는 다음 항목을 가진 struct입니다:

3. Connection Allowlist 헤더

Connection-Allowlist 응답 header는 컨텍스트가 연결할 수 있는 엔드포인트 집합을 정의하는 직렬화된 URL 패턴 문자열 목록을 포함합니다. 이 허용 목록은 주어진 컨텍스트에 대해 강제 적용되어, 선언된 패턴과 일치하지 않는 나가는 연결을 차단합니다. Connection-Allowlist-Report-Only 응답 header는 보고 전용 변형으로, 같은 방식으로 파싱되지만 나가는 연결을 차단하지 않고 위반 보고서만 보냅니다.

이 Connection Allowlist 헤더들은 structured headers이며, 그 값은 listinner lists입니다. 서버는 임의 개수의 항목이 있는 목록을 전달할 수 있지만, 첫 번째 항목만 사용됩니다. 목록의 추가 항목은 모두 무시됩니다.

inner liststrings로 직렬화된 URL Patterns 또는 token response-origin 중 하나를 포함할 수 있습니다. 이는 responseURLorigin과 일치하는 패턴을 나타냅니다. 예상치 못한 값은 무시됩니다.

inner list는 임의의 parameters를 가질 수 있습니다:

다른 모든 매개변수는 무시됩니다.

3.1. 파싱

response (response)가 주어졌을 때, 응답의 Connection Allowlists를 파싱하려면:
  1. allowlists를 빈 list로 둡니다.

  2. headerresponseheader list에서 `Connection-Allowlist`라는 이름의 list로서 구조화된 필드 값을 가져온 결과로 둡니다.

  3. header, responseURL, 그리고 enforce가 주어졌을 때 Connection Allowlist 헤더를 파싱합니다. 결과가 null이 아니면 이를 allowlistsinsert합니다.

  4. headerresponseheader list에서 `Connection-Allowlist-Report-Only`라는 이름의 list로서 구조화된 필드 값을 가져온 결과로 둡니다.

  5. header, responseURL, 그리고 report가 주어졌을 때 Connection Allowlist 헤더를 파싱합니다. 결과가 null이 아니면 이를 allowlistsinsert합니다.

  6. allowlists를 반환합니다.

structured header list (list), URL (response-url), 그리고 disposition (disposition)이 주어졌을 때 Connection Allowlist 헤더를 파싱하려면:
  1. listsize가 0이면 null을 반환합니다.

  2. list[0]이 inner list가 아니면 null을 반환합니다.

  3. allowlist를, 그 dispositiondispositionConnection Allowlist로 둡니다.

  4. list[0]의 각 item에 대해 For each:

    1. serialized patternnull로 둡니다.

    2. itemresponse-origin token인 경우:

      1. serialized patternresponse-urloriginASCII 직렬화로 설정합니다.

    3. itemstring이면 serialized patternitem으로 설정합니다.

    4. serialized patternnull이면 continue합니다.

    5. URL pattern을, serialized pattern가 주어지고 null을 기본 URL로 사용하여 HTTP structured field value에서 URL pattern을 빌드한 결과로 둡니다.

      이 단계에서 오류가 발생하면 continue합니다.

    6. URL patternallowlistallowlistAppend합니다.

  5. list[0]의 parameters 안의 각 keyvalue에 대해 For each:

    1. keyreport-to이고 valuetoken이면, allowlistreporting endpointvalue로 설정합니다.

    2. keyredirects이고 valuetoken이면:

      1. value가 "block"이면, allowlistredirectsblock으로 설정합니다.

      2. 그렇지 않으면, allowlistredirectsallow로 설정합니다.

    3. keywebrtc이고 valuetoken이면:

      1. value가 "block"이면, allowlistwebrtcblock으로 설정합니다.

      2. 그렇지 않으면, allowlistwebrtcallow로 설정합니다.

  6. allowlist를 반환합니다.

참고: 파싱 알고리즘에서 잘못된 입력은 모두 건너뜁니다. 파싱을 더 엄격하게 할 수도 있겠지만, 그렇게 하면 향후 유연성이 제한될 가능성이 큽니다.

3.2. 매칭

설정되는 연결의 유형에 따라, 작업할 request가 있을 수도 있고, URL만 있을 수도 있으며, 그보다 더 적은 정보만 있을 수도 있습니다. 예를 들어 dns-prefetch는 호스트에 대해서만 매칭할 수 있습니다. 아래 알고리즘들은 이러한 시나리오에서 연결 허용 목록 검사가 어떻게 동작하는지 설명합니다:

URL (url)과 connection allowlist (connection allowlist)가 주어졌을 때, URL을 Connection Allowlist에 매칭하려면 다음 단계를 실행합니다. 이 단계들은 success 또는 failure를 반환합니다.
  1. urllocal이면 success를 반환합니다.

  2. connection allowlistallowlist 안의 각 pattern에 대해 For each:

    1. patternurl이 주어졌을 때 URL pattern matchingnull을 반환하지 않으면, success를 반환합니다.

  3. failure를 반환합니다.

host (host)와 connection allowlist (connection allowlist)가 주어졌을 때, host를 Connection Allowlist에 매칭하려면 다음 단계를 실행합니다. 이 단계들은 success 또는 failure를 반환합니다.
  1. connection allowlistallowlist 안의 각 pattern에 대해 For each:

    1. input을 새 URLPatternInit 딕셔너리로 두고, 그 hostnamepatternhostname component로 설정합니다.

    2. host-only pattern을, input, 기본 URL로 null, 그리고 옵션으로 빈 map이 주어졌을 때 URL pattern을 생성한 결과로 둡니다.

    3. synthetic url을 "https://"와 host를 연결한 값을 URL로 parsing한 결과로 둡니다.

    4. host-only patternsynthetic url이 주어졌을 때 URL pattern matchingnull을 반환하지 않으면, success를 반환합니다.

  2. failure를 반환합니다.

참고: hostname component만으로 새 패턴을 만들고 host에 대한 URL을 합성함으로써, 허용 목록의 _어떤_ 패턴이라도 임의의 프로토콜, 임의의 포트, 임의의 경로 등으로 해당 호스트에 대한 요청을 허용할 수 있다면 매칭을 반환할 수 있습니다.

url이 Connection Allowlists에 의해 차단되어야 하는지 알고리즘은 URL (url), environment (environment), 그리고 listconnection allowlists (connection allowlists)를 받습니다. 이는 allowed 또는 blocked 중 하나를 반환합니다:
  1. connection allowlists의 각 connection allowlist에 대해 For each:

    1. urlconnection allowlistmatches하면, continue합니다.

    2. url, environment, 그리고 connection allowlist가 주어졌을 때 위반을 보고합니다.

    3. connection allowlistdispositionenforce이면, blocked를 반환합니다.

  2. allowed를 반환합니다.

request가 Connection Allowlists에 의해 차단되어야 하는지 알고리즘은 request (request)를 받고, allowed 또는 blocked 중 하나를 반환합니다:
  1. allowlistsrequestpolicy containerconnection allowlists로 둡니다.

  2. allowlists의 각 allowlist에 대해 For each:

    1. requestURL listsize가 1보다 크면:

      1. allowlistredirectsallow이면, continue합니다.

      2. requesturl, requestclient, 그리고 allowlist가 주어졌을 때 위반을 보고합니다.

        참고: 리디렉션이 차단될 때, 리디렉션 대상에 대해 필요한 것보다 더 많은 정보를 누출하지 않기 위해 의도적으로 requesturl을 보고하고 그 current url은 보고하지 않습니다.

      3. allowlistdispositionenforce이면, blocked를 반환합니다.

      4. Continue합니다.

    2. requesturlallowlistmatches하면, continue합니다.

    3. requesturl, requestclient, 그리고 allowlist가 주어졌을 때 위반을 보고합니다.

    4. allowlistdispositionenforce이면, blocked를 반환합니다.

  3. allowed를 반환합니다.

host가 Connection Allowlists에 의해 차단되어야 하는지 알고리즘은 host (host), environment (environment), 그리고 listconnection allowlists (connection allowlists)를 받습니다. 이는 allowed 또는 blocked 중 하나를 반환합니다:
  1. connection allowlists의 각 connection allowlist에 대해 For each:

    1. hostconnection allowlisthost-matches하면, continue합니다.

    2. host, environment, 그리고 connection allowlist가 주어졌을 때 위반을 보고합니다.

    3. connection allowlistdispositionenforce이면, blocked를 반환합니다.

  2. allowed를 반환합니다.

WebRTC가 Connection Allowlists에 의해 차단되어야 하는지 알고리즘은 environment settings object (environment)를 받고 allowed 또는 blocked 중 하나를 반환합니다:
  1. allowlistsenvironmentpolicy containerconnection allowlists로 둡니다.

  2. allowlists의 각 allowlist에 대해 For each:

    1. allowlistwebrtcallow이면, continue합니다.

    2. "webrtc", environment, 그리고 allowlist가 주어졌을 때 위반을 보고합니다.

    3. allowlistdispositionenforce이면, blocked를 반환합니다.

  3. allowed를 반환합니다.

3.3. 보고

다른 정책 메커니즘과 마찬가지로, Connection Allowlists는 각 위반을 허용 목록 헤더에 지정된 Reporting API 엔드포인트로 보고합니다. 위반은 다음 딕셔너리 유형으로 표현됩니다:

enum ConnectionAllowlistDisposition { "enforce", "report" };

dictionary ConnectionAllowlistViolationReport : ReportBody {
  USVString url;
  USVString connection;
  sequence<DOMString> allowlist;
  ConnectionAllowlistDisposition disposition;
};

ConnectionAllowlistViolationReportconnection은 허용 목록을 위반한 연결의 직렬화된 URL입니다.

ConnectionAllowlistViolationReportallowlist는 위반된 allowlist입니다.

ConnectionAllowlistViolationReportdispositionallowlistdisposition입니다.

URL 또는 string "webrtc" (resource URL), environment (environment), 그리고 connection allowlist (allowlist)가 주어졌을 때 위반을 보고하려면:
  1. allowlistreporting endpointnull이면 반환합니다.

  2. violation을 다음과 같이 초기화된 새 ConnectionAllowlistViolationReport로 둡니다:

url

environmentcreation URL보고서에 사용하기 위해 제거한 값입니다.

connection

resource URLURL이면, resource URL보고서에 사용하기 위해 제거한 값입니다.

그렇지 않으면 resource URL입니다.

allowlist

allowlistallowlist 안의 각 패턴을 직렬화한 결과를 포함하는 새 목록입니다.

disposition

allowlistdisposition입니다.

  1. environment를 컨텍스트로, "connection-allowlist"를 유형으로, allowlistreporting endpoint를 대상으로, violation을 데이터로 하여 보고서를 생성하고 큐에 넣습니다.

4. 몽키 패치

4.1. Fetch와의 통합

같은 목적을 수행하는 다른 검사들과 함께 Fetch § 4.1 Main fetch에 차단 검사를 추가하여 requests를 처리합니다:

Main Fetch에서, 7단계를 다음과 같이 조정합니다:
  1. If should request be blocked due to a bad port, should fetching request be blocked as mixed content, should request be blocked by Content Security Policy, should request be blocked by Connection Allowlists, or should request be blocked by Integrity Policy Policy returns blocked, then set response to a network error.

Fetch는 requests에 기반하지 않는 API의 연결 설정에 사용되는 더 낮은 수준의 알고리즘도 정의합니다. DNS prefetch, Web Transport 등과 같은 것을 처리하기 위해 resolve an originobtain a connection에 연결합니다:

resolve an origin에서, 주어진 호스트에 대한 연결을 어떤 패턴이라도 잠재적으로 허용할 수 있는지 판단하기 위해 위의 host-only 매칭 알고리즘을 호출합니다. 허용할 수 없다면 resolution을 실패시킵니다.
  1. originhost, environment, 그리고 allowlists에 대해 실행했을 때 should host be blocked by Connection Allowlistsblocked를 반환하면, failure를 반환합니다.
obtain a connection에서, 현재 2단계 전에 검사를 추가합니다:
  1. url, environment, 그리고 allowlists에 대해 실행했을 때 should url be blocked by Connection Allowlistsblocked를 반환하면, failure를 반환합니다.

Fetch 변경 사항은 사용해야 할 허용 목록과 보고에 사용할 컨텍스트를 식별하기 위해 하위 수준 알고리즘의 호출 지점에 추가 정보를 전달하도록 요구할 것입니다. 대신 해당 호출 지점들이 직접 검사를 수행하도록 요청하는 편이 더 나을 수도 있습니다. 제 느낌으로는 로직을 중앙화하는 편이 더 성공적이겠지만, 부분적으로 접근하는 편이 더 단순할 수도 있습니다.

4.2. HTML과의 통합

위 내용을 HTML에 통합하기 위해, policy container structconnection allowlistslist를 포함하는 새 connection allowlists 항목을 추가합니다. 이는 fetch response에서 policy container를 생성하는 알고리즘에 단계를 추가하여 채워집니다:

  1. responseresult로 Integrity-Policy 헤더를 파싱합니다.

  2. resultconnection allowlistsresponse가 주어졌을 때 응답의 Connection Allowlists를 파싱한 결과로 설정합니다.
  3. result를 반환합니다.

참고: early response의 policy container가 early hint 링크를 가져올 때 이미 사용되므로, Early hint 통합에는 추가 변경이 필요하지 않습니다.

4.3. WebRTC와의 통합

WebRTC 연결을 제한하기 위해, [webrtc]는 candidate가 administratively prohibited인지 판단하는 동안 should WebRTC be blocked by Connection Allowlists 알고리즘을 호출할 수 있습니다.

4.4. 서비스 워커와의 통합

서비스 워커 자체의 policy container를 적용하는 기본 동작을 넘어서, 서비스 워커는 WindowClient API를 사용해 탐색을 호출할 때 자체 연결 허용 목록을 적용해야 합니다.

navigate()openWindow(url) 알고리즘은 둘 다 다음과 같이 패치되어야 합니다:

  1. url, thisrelevant settings object, 그리고 thisrelevant settings objectpolicy containerconnection allowlists에 대해 실행했을 때 should url be blocked by Connection Allowlistsblocked를 반환하면, "SecurityError" DOMException으로 거부된 promise를 반환합니다.

navigate()는 현재 문서를 탐색의 sourceDocument로 전달합니다. 이는 약간의 실수처럼 보입니다. 논의를 참조하십시오.

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

5.1. 동일 출처 컨텍스트

§ 1.1 위협 모델에 설명된 위협 모델은 의도적으로 좁으며, 개발자는 여기서 설명한 허용 목록 메커니즘을 자신의 방어에 어떻게 계층화할지 신중하게 고려해야 합니다. 가장 두드러지게, 이 메커니즘은 컨텍스트별이며 출처 전체에 적용되는 것이 아닙니다. 이는 스크립팅 접근 권한을 가진 공격자가 제한이 더 낮은 동일 출처 컨텍스트를 찾아 컨텍스트의 허용 목록을 우회할 수 있는 넓은 기회를 남깁니다. HTML의 policy container와의 통합은 그러한 가능성 중 일부를 다루지만, 다른 가능성도 존재할 가능성이 높습니다. 예를 들어 공격자는 프레임 트리를 통해 제한이 더 낮은 부모에 도달하거나, opener 관계를 유지하는 새 창을 window.open()으로 열 수 있을지도 모릅니다. 따라서 문서의 출처를 (response-origin을 통해 또는 명시적으로) 허용 목록에 넣는 것은 그 자체로 완전한 해결책이 아닙니다.

개발자가 sandbox 속성 또는 Content Security Policy의 sandbox 지시문을 사용하여 허용 목록이 적용된 컨텍스트를 일반 출처에서 격리함으로써 이 위험을 피할 수 있는 시나리오도 있습니다. 이러한 경우 어떤 문서도 동일 출처가 아니며, 경계를 유지하기가 더 쉬울 것입니다.

또한 개발자가 의존성의 허용 목록에 대해 어느 정도 제어권을 갖도록 하는 것이 이상적일 것입니다. required document policy 또는 [csp-embedded-enforcement]] 같은 것에 뿌리를 둔 옵트인 메커니즘을 탐색해 보면 도움이 될 수 있습니다. [WICG/connection-allowlists Issue #1]

5.2. 서비스 워커

Service Workers는 다른 동일 출처 컨텍스트와 마찬가지로 허용 목록과 관련된 이야기를 복잡하게 만듭니다. 서비스 워커는 자신이 관리하는 각 문서와 별개의 policy container를 가지기 때문에, 서비스 워커의 허용 목록과 다른 허용 목록을 가진 문서에서 시작된 메시지나 요청에 응답할 가능성이 충분히 있습니다. 이 제안은 다른 정책의 설계를 따르며, 이러한 능력 차이를 허용합니다.

개발자가 서비스 워커의 요청 생성 능력을 제한하려면, 워커 스크립트와 함께 허용 목록을 전달할 수 있습니다. 다만 이 허용 목록이 서비스할 수 있는 모든 문서의 허용 목록의 상위 집합인지 확인해야 합니다.

5.3. DNS

Connection Allowlists는 DNS 요청을 보내기 전에 허용 목록을 확인하도록 Fetch의 resolve an origin 알고리즘을 변경하여, DNS 조회를 통한 유출 위험을 완화하는 것을 목표로 합니다. 이는 요청을 보내는 요소와 API 사용으로 발생하는 암시적 조회(img 태그, fetch() 등)뿐만 아니라 dns-prefetch 같은 메커니즘에 의해 트리거되는 명시적 조회도 다룹니다.

그렇기는 해도, 허용 목록은 주어진 엔드포인트가 허용 가능한지 판단하기 위해 URL 기반 매칭에 의존합니다. 이는 DNS 조작에 대한 방어가 아니며, 요청에 관여하는 DNS 서버(여러 서버와의 잠재적 통신을 포함하는 DNS resolution의 재귀적 성격 포함)를 제한하지도 않고, CNAME 같은 구조가 허용 목록 밖의 도메인에 대한 추가 조회를 유발하는 것을 제한하지도 않습니다. 마찬가지로 허용 목록은 DNS가 가리키는 서버가 기대하는 서버인지 보장할 수 없습니다.

개발자는 인증된 연결에 의존하여 DNS 하이재킹 및/또는 리바인딩의 위험을 완화해야 합니다. 보안 프로토콜만 허용 목록에 넣으면, TLS 핸드셰이크가 관련 이름의 인증서 소유를 요구하므로 DNS를 제어하는 공격자가 트래픽을 임의의 엔드포인트로 전환하기 훨씬 어려워집니다.

허용 목록의 패턴을 보안 프로토콜을 나타내는 것들로 제한해야 할까요? 아니면 비보안 출처에 대해서는 헤더 전체를 미뤄야 할까요?

5.4. postMessage(...)

이 제안은 전적으로 네트워크 연결에만 관심을 두며, 이는 postMessage(message, options), MessageChannel, BroadcastChannel 등과 같은 명시적 통신 채널을 통한 통신도 포함될 것으로 기대하는 개발자에게는 놀라울 수 있습니다. 이들도 모두 허용 목록과 의미 있게 비교할 수 있는 출처 기반 모델에 들어맞으므로, 이러한 것들을 포함하도록 모델을 확장하는 것이 타당할 수 있습니다.

5.5. 리디렉션

기본적으로 Connection Allowlists는 모든 리디렉션을 차단합니다. 이는 오픈 리디렉션 또는 다른 서버 측 리디렉션 메커니즘을 통한 데이터 유출을 방지하려는 보수적인 자세입니다. 문서에 허용 목록이 강제 적용되는 경우, 리디렉션을 초래하는 모든 요청은 허용 목록이 명시적으로 허용을 선택하지 않는 한 차단됩니다.

redirects 매개변수는 개발자가 이 동작을 제어할 수 있게 합니다.

block(기본값)으로 설정하면, 리디렉션 체인 길이가 1보다 큰 모든 요청이 차단됩니다.

allow로 설정하면, 허용 목록은 최초 요청에만 강제 적용됩니다. 최초 요청이 허용 목록과 일치하면, 이후의 모든 리디렉션은 위치와 관계없이 허용됩니다. 이 모드는 데이터 보안에 대한 책임을 서버로 이동시킵니다. 요청이 클라이언트를 떠나도록 허용된 뒤에는, 서버가 사용자의 데이터를 신뢰할 수 없는 위치로 리디렉션하지 않도록 보장할 책임이 있습니다.

이 접근 방식은 애플리케이션마다 서로 다른 보안 요구사항이 있음을 인정합니다. 매우 민감한 애플리케이션은 모든 리디렉션을 차단하도록 선택할 수 있고, 다른 애플리케이션은 신뢰하는 엔드포인트가 리디렉션을 올바르게 처리한다고 의존할 수 있습니다.

다음 헤더가 있는 문서를 생각해 보십시오:
Connection-Allowlist: ("https://api.example")

https://api.example/data로의 요청이 https://api.example/new-data로 향하는 302 Found 리디렉션을 반환하면, 리디렉션이 기본적으로 차단되므로 차단됩니다.

대신 헤더가 다음과 같다면:

Connection-Allowlist: ("https://api.example");redirects=allow

https://api.example/data로의 같은 요청은 허용되며, 이후 https://api.example/new-data(또는 심지어 https://attacker.com/)로 향하는 리디렉션도 허용됩니다.

마지막으로, 향후 호환성을 위해 알 수 없는 토큰은 allow로 처리됩니다:

Connection-Allowlist: ("https://api.example");redirects=some-future-policy

이 경우 redirects 매개변수는 존재하지만 그 값 some-future-policy는 알 수 없습니다. 사용자 에이전트는 이를 allow로 처리하며, 리디렉션은 허용됩니다. 이를 통해 기존 사이트를 깨뜨리지 않고 향후 추가 동작을 도입할 가능성을 남길 수 있습니다.

5.6. WebRTC

기본적으로 Connection Allowlists는 모든 WebRTC 연결을 차단합니다. 이는 URL 패턴만으로는 제한하기 어려울 수 있는 WebRTC의 고유한 네트워킹 특성을 통한 데이터 유출 위험을 완화하려는 보수적인 자세입니다.

webrtc 매개변수는 개발자가 이 동작을 제어할 수 있게 합니다.

block(기본값)으로 설정하면, WebRTC 연결을 설정하려는 모든 시도가 차단됩니다.

allow로 설정하면, WebRTC 연결이 허용됩니다.

다음 헤더가 있는 문서를 생각해 보십시오:
Connection-Allowlist: ("https://api.example")

WebRTC는 기본적으로 차단되므로, WebRTC 연결을 설정하려는 모든 시도는 차단됩니다.

대신 헤더가 다음과 같다면:

Connection-Allowlist: ("https://api.example"); webrtc=allow

WebRTC 연결은 허용됩니다.

6. 구현 고려사항

6.1. WebSockets

WebSocket 연결은 ws 또는 wss 스킴을 지정하는 패턴이 아니라, httphttps 패턴에 의해 다뤄진다는 점을 기억하면 도움이 됩니다. WebSocket 연결을 설정할 때, 1단계는 이러한 websocket 전용 스킴을 각각 httphttps로 다시 씁니다. 이는 "ws://socket.example" 같은 패턴을 포함하는 허용 목록이 의도한 효과를 내지 못한다는 뜻입니다. 해당 패턴은 리소스 요청과 결코 매칭되지 않기 때문입니다.

적합성

문서 규약

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

이 사양의 모든 텍스트는 명시적으로 비규범으로 표시된 섹션, 예제, 참고를 제외하고는 규범적입니다. [RFC2119]

이 사양의 예제는 “예를 들어”라는 단어로 도입되거나, 다음과 같이 class="example"을 사용하여 규범적 텍스트와 구분됩니다:

이는 정보 제공용 예제의 예입니다.

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

참고, 이는 정보 제공용 참고입니다.

색인

이 사양에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. URL: https://w3c.github.io/webappsec-csp/
[DOCUMENT-POLICY]
Document Policy. 커뮤니티 그룹 보고서 초안. URL: https://wicg.github.io/document-policy/
[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/
[REPORTING]
Douglas Creager; Ian Clelland; Mike West. Reporting API. URL: https://w3c.github.io/reporting/
[RFC2119]
S. Bradner. RFC에서 요구 수준을 나타내는 데 사용하는 핵심 단어. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC9651]
M. Nottingham; P-H. Kamp. HTTP를 위한 구조화된 필드 값. 2024년 9월. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc9651/
[SERVICE-WORKERS]
Monica CHINTALA; Yoshisato Yanagisawa. Service Workers Nightly. URL: https://w3c.github.io/ServiceWorker/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[URLPATTERN]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern Standard. Living Standard. URL: https://urlpattern.spec.whatwg.org/
[WEB-BLUETOOTH]
Jeffrey Yasskin. Web Bluetooth. URL: https://webbluetoothcg.github.io/web-bluetooth/
[WEB-SMART-CARD]
Web Smart Card API. 비공식 제안 초안. Draft. URL: https://wicg.github.io/web-smart-card/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[WEBRTC]
Cullen Jennings; et al. WebRTC: Real-Time Communication in Browsers. URL: https://w3c.github.io/webrtc-pc/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

비규범적 참고 문헌

[CSP-EMBEDDED-ENFORCEMENT]
Mike West; Antonio Sartori. Content Security Policy: Embedded Enforcement. URL: https://w3c.github.io/webappsec-cspee/

IDL 색인

enum ConnectionAllowlistDisposition { "enforce", "report" };

dictionary ConnectionAllowlistViolationReport : ReportBody {
  USVString url;
  USVString connection;
  sequence<DOMString> allowlist;
  ConnectionAllowlistDisposition disposition;
};

이슈 색인

Fetch 변경 사항은 사용해야 할 허용 목록과 보고에 사용할 컨텍스트를 식별하기 위해 하위 수준 알고리즘의 호출 지점에 추가 정보를 전달하도록 요구할 것입니다. 대신 해당 호출 지점들이 직접 검사를 수행하도록 요청하는 편이 더 나을 수도 있습니다. 제 느낌으로는 로직을 중앙화하는 편이 더 성공적이겠지만, 부분적으로 접근하는 편이 더 단순할 수도 있습니다.
navigate()는 현재 문서를 탐색의 sourceDocument로 전달합니다. 이는 약간의 실수처럼 보입니다. 논의를 참조하십시오.
개발자가 자신의 의존성의 허용 목록을 어느 정도 제어할 수 있게 하는 것도 이상적일 것입니다. required document policy 또는 [csp-embedded-enforcement]] 같은 것에 뿌리를 둔 옵트인 메커니즘을 탐색해 보면 도움이 될 수 있습니다. [WICG/connection-allowlists Issue #1]
허용 목록의 패턴을 보안 프로토콜을 나타내는 것들로 제한해야 할까요? 아니면 비보안 출처에 대해서는 헤더 전체를 미뤄야 할까요?