콘텐츠 보안 정책: 내장된 시행

W3C 작업 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/WD-csp-embedded-enforcement-20260507/
최신 공개 버전:
https://www.w3.org/TR/csp-embedded-enforcement/
편집자 초안:
https://w3c.github.io/webappsec-cspee/
이전 버전:
이력:
https://www.w3.org/standards/history/csp-embedded-enforcement/
피드백:
public-webappsec@w3.org 에 제목 줄 “[csp-embedded-enforcement] … 메시지 주제 …”로 보내십시오 (아카이브)
Github
편집자:
(Google Inc.)
(Google Inc.)
참여:
이슈 제출 (열린 이슈)
테스트:
web-platform-tests content-security-policy/embedded-enforcement/ (진행 중인 작업)

초록

이 문서는 웹 페이지가 프레임에 CSP 요구사항을 부과하여, 그 프레임이 특정 제한 집합을 스스로 시행하는 데 동의하는 경우에만 문서를 임베드할 수 있게 하는 메커니즘을 정의한다.

이 문서의 상태

이 절은 이 문서가 발행된 시점의 상태를 설명한다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 기술 보고서 색인에서 확인할 수 있다.

이 문서는 Web Application Security Working GroupRecommendation track을 사용하여 작업 초안으로 발행했다. 이 문서는 W3C 권고안이 되는 것을 목표로 한다.

이 명세에 대한 논의에는 (보관된) 공개 메일링 리스트 public-webappsec@w3.org (지침 참조)를 사용하는 것이 권장된다. 이메일을 보낼 때는 제목에 “csp-embedded-enforcement”라는 텍스트를 넣어 주기 바라며, 가급적 다음과 같은 형식을 사용하기 바란다: “[csp-embedded-enforcement] …의견 요약…

작업 초안으로 발행되었다고 해서 W3C와 그 회원들이 이를 승인했다는 의미는 아니다. 이 문서는 초안 문서이며 언제든지 다른 문서로 갱신, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 부적절하다.

이 문서는 Web Application Security Working Group에서 작성했다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했다. W3C는 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지한다. 해당 페이지에는 특허 공개 방법에 대한 지침도 포함되어 있다. 개인이 자신이 아는 특허가 필수 청구항을 포함한다고 실제로 알고 있는 경우, 그 개인은 W3C 특허 정책 제6절에 따라 해당 정보를 공개해야 한다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받는다.

1. 소개

이 절은 규범적이지 않다.

콘텐츠 보안 정책은 교차 사이트 스크립팅 공격에 대한 훌륭한 방어 수단으로, 개발자가 악성 스크립트, 스타일 및 기타 리소스 유형의 삽입에 대해 자신의 사이트를 강화할 수 있게 한다. 그러나 이는 개발자에게 iframe을 통해 로드된 제3자 콘텐츠에 제한을 적용할 수 있는 능력을 제공하지는 않는다. CSP를 이러한 제3자 컨텍스트에 직접 적용하도록 허용하는 것은 위험할 수 있다. CSP는 리소스 로딩에 대해 상당히 세분화된 제어를 제공하며, 특정 스크립트에 대한 접근을 거부함으로써 원래는 안전한 페이지에 취약점을 도입할 가능성이 매우 높다. 우리는 과거의 X-XSS-Protection과 같은 기능에서 이러한 종류의 문제를 보았으므로, 이를 새로운 형태로 다시 도입하지 않도록 주의해야 한다.

그렇지만 위젯, 광고 및 기타 종류의 제3자 콘텐츠에 제한을 둘 수 있다면 매우 유용할 것이다. 이 문서는 임베드된 콘텐츠의 명시적 옵트인에 의존하는 메커니즘을 제안하며, 이는 위젯이 임베더와 협력하여 합리적인 제한 집합을 협상할 수 있게 할 것이다.

요약하면, 임베더는 iframe 요소에 속성을 설정하여 콘텐츠 보안 정책을 제안한다. 이 정책은 프레임된 콘텐츠에 대한 HTTP 요청과 함께 HTTP 요청 헤더 (`Sec-Required-CSP`)로 전송된다. 임베드된 콘텐츠가 해당 정책을 수락할 수 있다면, 응답과 함께 `Content-Security-Policy` 또는 `Allow-CSP-From` 헤더를 반환하여 이를 시행할 수 있다.

응답에 임베더가 요청한 정책만큼 엄격한 정책이 포함되어 있거나, 임베더가 제공한 정책을 수락한다면 사용자 에이전트는 임베드된 콘텐츠를 렌더링한다. 그러한 단언이 없으면 응답은 차단된다.

1.1. 예제

MegaCorp Inc.는 다양한 출판물에 게재되는 광고가 안전성 검사를 받은 신뢰할 수 있는 출처의 스크립트만 포함하도록 잠기기를 원한다. 이들은 광고를 iframe 요소를 통해 포함하고 csp 속성을 사용함으로써 이를 수행할 수 있다:
<iframe src="https://advertisements-r-us.example.com/ad1.cfm"
        csp="script-src https://trusted-cdn.example.com/">
</iframe>

이는 다음과 같이 `Sec-Required-CSP` 헤더가 있는 advertisements-r-us.example.com에 대한 요청을 생성한다:

GET / HTTP/1.1
Host: advertisements-r-us.example.com
...
Sec-Required-CSP: script-src https://trusted-cdn.example.com/
...

광고 서버는 이 요청 헤더를 파싱하고, 이를 수락할 수 있다고 판단한 뒤, 임베더(https://example.com)가 부과한 제한을 준수하겠다고 사용자 에이전트에 알리는 헤더를 응답에 추가한다:

HTTP/1.1 200 OK
...
Allow-CSP-From: https://example.com
위 예제의 광고 서버는 임베더가 요구하는 정책만큼 강력한 자체 `Content-Security-Policy` 헤더를 내보내어 제한을 수락할 수도 있다. 예를 들어, 임베더가 허용하는 것과 관계없이 플러그인이 로드되지 않도록 보장하고 싶을 수 있다. 서버는 임베더의 제한을 포함하고 그 위에 더 많은 제한을 추가하는 정책을 내보냄으로써 이를 수행할 수 있다:
HTTP/1.1 200 OK
...
Content-Security-Policy: script-src https://trusted-cdn.example.com/; object-src 'none'

응답이 단언한 정책이 요청이 요구한 정책보다 엄격하게 더 적은 요청만 허용하므로, 프레임은 성공적으로 로드된다.

서버는 두 개의 정책, 즉 임베더의 제한을 정확히 반영하는 정책 하나와 이를 더 강화하는 또 다른 정책을 전달할 수도 있다:

HTTP/1.1 200 OK
...
Content-Security-Policy: script-src https://trusted-cdn.example.com/, object-src 'none'

`Content-Security-Policy` 헤더 값의 ","는 문자열을 두 개의 직렬화된 정책으로 분할하며, 각각이 시행된다. 사용자 에이전트는 응답과 함께 전달된 정책 중 하나가 요구사항과 일치하는지 검증하고, 추가 정책은 페이지의 유효 정책을 더 제한적으로 만들 수밖에 없으므로 프레임이 성공적으로 로드되도록 허용한다.

2. 프레임워크

높은 수준에서, 이 문서는 임베디가 임베더가 지정한 제한 집합에 옵트인할 수 있게 하는 메커니즘을 설명한다. 이 메커니즘은 몇 가지 단계를 포함한다:

  1. 임베더는 csp 속성을 iframe 요소에 사용하여 필수 정책을 지정한다. 이는 § 2.1 <iframe>의 csp 속성에서 더 자세히 설명한다.

  2. 해당 속성의 값은 `Sec-Required-CSP` 요청 헤더로 함께 전송되며, iframe자식 navigable을 대상으로 하는 모든 navigation request에 포함된다. 이 헤더는 § 2.2 Sec-Required-CSP HTTP 요청 헤더에서 더 자세히 설명한다.

  3. 서버는 `Sec-Required-CSP` 헤더를 검사하여 필수 정책을 수락할 것인지 결정할 수 있다. 수락하려는 경우, 필수 정책만큼 강력한 정책을 포함하는 `Content-Security-Policy` 헤더를 응답에 전송하여 암시적으로 옵트인하거나, 임베딩 출처가 원하는 어떤 정책이든 설정할 수 있게 하는 `Allow-CSP-From` 헤더를 응답에 전송하여 명시적으로 옵트인할 수 있다. 명시적 메커니즘은 간단하며 § 2.3 Allow-CSP-From HTTP 응답 헤더에서 설명한다. 암시적 메커니즘은 꽤 복잡하며, § 3 암시적 정책 수락 절 전체를 구성한다.

    서버가 필수 정책을 수락하고 싶지 않다면 명시적 오류를 반환하거나, 일치하는 `Content-Security-Policy` 헤더나 `Allow-CSP-From` 헤더 없이 일반 데이터를 그대로 반환할 수 있다. 이 경우 사용자 에이전트는 응답을 차단한다. HTML의 navigate 알고리즘과의 통합은 § 2.4 HTML과의 통합에서 설명되며, 차단 메커니즘은 § 4.1 request에 대한 response가 requiredCSP에 의해 차단되는가?에 자세히 명시되어 있다.

2.1. <iframe>csp 속성

iframe 요소는 임베드된 문서가 스스로 시행하기로 동의해야 하는 정책을 지정하는 csp 속성을 가진다. 예를 들어, 다음 HTML은 https://embedee.example.com/을 로드하고, object-src 'none'이 그 문서에 대해 시행되도록 보장한다:

<iframe src="https://embedee.example.com/" csp="object-src 'none'">
</iframe>

문자열 (value)은 다음 모든 문장이 참인 경우, 주어진 요소 (element)의 csp 속성에 대한 유효한 속성 값이다:

  1. value가 빈 문자열이 아니다.

  2. value길이가 4096 이하이다.

    참고: 서버를 잠재적으로 혼란스러운 입력으로부터 보호하기 위해 csp 속성 값에 최대 길이를 적용한다. 아래 § 5.4 헤더 길이를 보라.

  3. value[CSP]에 정의된 serialized-policy ABNF 문법과 일치한다.

  4. 다음 문장 중 하나가 참이다:

    1. elementnode documentpolicy containerrequired CSPnull이다.

    2. value를 "enforce"로 파싱한 결과가 elementnode documentpolicy containerrequired CSP에 의해 포섭된다.

  5. value를 "enforce"로 파싱한 결과가 다음 지시문 중 어떤 것도 포함하지 않는 directive set을 가진다:

다음 문자열들은 유효한 CSP 문법이므로 csp 속성의 유효한 값이다:
  • script-src 'none'

  • script-src 'self'; object-src 'none'; sandbox

  • not-a-directive https://whatever.not-a-tld

참고: 마지막 항목은 의미 있는 정책을 표현하지 않더라도, 향후 CSP 구문과의 전방 호환성을 유지하기 위해 유효한 것으로 간주한다.

반면 다음은 CSP 구문과 일치하지 않으므로, 유효한 속성 값으로 간주되지 않는다:

  • script-src *\nInjected-Header: XSS!

  • 💩

참고: csp 속성에 허용하는 값에 주의해야 한다. 그 내용은 결국 HTTP 요청 헤더로 반사되기 때문이다. 이 우려는 에서 조금 더 자세히 논의한다.

iframecsp 속성에는 다음 WebIDL 문법 [WEBIDL]로 정의되는 대응 IDL 속성이 있다:

partial interface HTMLIFrameElement {
  [CEReactions] attribute DOMString csp;
};

csp IDL 속성은 요소의 csp 속성반영해야 한다.

이를 모든 HTML에 업스트림한다.

2.2. Sec-Required-CSP HTTP 요청 헤더

임베드된 리소스가 임베더의 요구사항을 준수할 의사가 있는지 여부를 결정할 수 있도록 하기 위해, iframecsp 속성에 표현된 정책은 "Sec-Required-CSP" HTTP 요청 헤더를 통해 영향을 받는 navigation request와 함께 전달된다. 헤더의 값은 다음 ABNF [RFC5234]로 표현된다:

Sec-Required-CSP = serialized-policy

사용자 에이전트는 "Sec-Required-CSP"라는 이름의 HTTP 응답 헤더 필드를 하나보다 많이 보내서는 안 되며, 그러한 헤더는 하나보다 많은 serialized-policy를 포함해서는 안 된다.

서버는 수신한 첫 번째 해당 헤더의 첫 번째 정책만 처리해야 한다. 에서 논의하듯, 서버는 정책을 클라이언트에 단순히 반사하는 것의 영향을 신중히 고려해야 한다. 서버가 임베더의 요구사항을 단순히 수락하려는 경우, `Allow-CSP-From` 헤더가 더 안전한 선택이다.

이 헤더는 HTML의 navigate 알고리즘의 일부로 설정된다(다음 알고리즘을 호출하는 훅에 대한 자세한 내용은 § 2.4 HTML과의 통합을 보라):

주어진 request (request)와 직렬화된 CSP-또는-null (requirement)에 대해 Sec-Required-CSP 헤더를 설정하려면, 다음 단계를 실행한다:
  1. requestnavigation request가 아니면 반환한다.

  2. requirementnull이면 반환한다.

  3. Assert: requirement[CSP]에 정의된 serialized-policy 문법과 일치하는 serialized CSP이다.

  4. requestheader list에 "`Sec-Required-CSP`"라는 이름과 requirement 값을 가진 헤더를 추가한다.

2.3. Allow-CSP-From HTTP 응답 헤더

임베디는 "Allow-CSP-From" HTTP 응답 헤더로 응답함으로써 임베더가 지정한 정책을 수락하는 데 옵트인할 수 있다. 헤더의 값은 다음 ABNF [RFC5234]로 표현된다:

Allow-CSP-From = origin-or-null / wildcard

2.4. HTML과의 통합

  1. iframe 요소는 § 2.1 <iframe>의 csp 속성에서 정의된 csp 속성을 가진다.

  2. policy container structrequired CSP 항목을 추가한다. 이는 serialized CSP 또는 null이며, 처음에는 null이다.

  3. target snapshot params structrequired CSP 항목을 추가한다. 이는 serialized CSP 또는 null이다.

  4. HTML의 snapshotting target snapshot params 알고리즘을 갱신하여 새 required CSP 항목을 targetNavigable이 주어졌을 때 determine the required CSP의 결과로 설정한다.

  5. navigation params structrequired CSP 항목을 추가한다. 이는 serialized CSP 또는 null이다.

  6. navigate 알고리즘을 갱신하여, 18.7.7단계에서 생성된 navigation params structrequired CSPtargetSnapshotParamsrequired CSP로 설정한다.

  7. HTML의 create navigation params by fetching 알고리즘에서 request가 생성된 뒤 다음 단계를 추가한다:

    1. requesttargetSnapshotParamsrequired CSP에 대해 set the Sec-Required-CSP header를 실행한다.

  8. 반환되는 navigation paramsrequired CSPtargetSnapshotParamsrequired CSP로 설정하도록 create navigation params by fetching을 갱신한다.

  9. 반환되는 navigation paramsrequired CSPtargetSnapshotParamsrequired CSP로 설정하도록 create navigation params from a srcdoc resource를 갱신한다.

  10. HTML의 creating a policy container from a fetch response 알고리즘에 선택적 requiredCSP (null을 기본값으로 하는 serialized CSP 또는 null) 인수를 추가하고, 다음 단계를 추가한다:

    1. requiredCSP가 null이 아니면:

      1. required policyrequiredCSP를 "enforce"로 파싱한 결과로 둔다.

      2. response policiesresponse의 Content Security Policies를 파싱한 결과로 둔다.

      3. required policy, responseurlorigin, response policies, 그리고 responseurlorigin에 대해 실행했을 때 § 3.2.1 CSP 목록 포섭이 "Does Not Subsume"를 반환하면:

        1. required policyresultCSP list추가한다.

        참고: 응답의 정책이 이미 필수 정책을 포섭한다면, 필수 정책을 policy container에 추가하지 않는다. 이는 임베더가 특정 nonce(예: nonce-abc)를 요구하고, 임베디가 자체 호환 nonce(예: nonce-xyz)를 제공하는 경우, 사용자 에이전트가 임베디의 nonce만 시행하도록 보장한다. 둘 다 추가한다면, 어떤 스크립트도 두 nonce를 동시에 만족할 수 없으므로 문서는 사실상 모든 스크립트를 차단하게 된다.

      4. resultrequired CSPrequiredCSP로 설정한다.

  11. targetSnapshotParamsrequired CSPcreating a policy container from a fetch response에 전달하도록 create navigation params by fetching을 갱신한다.

  12. HTML의 navigate 알고리즘에서 탐색을 차단하게 하는 조건 목록에 다음을 추가한다(예: X-Frame-Options 검사 뒤):

2.4.1. 필수 CSP

주어진 navigable (navigable)에 대해 required CSP를 결정하려면, 다음 단계를 실행한다:
  1. navigablechild navigable이 아니면 null을 반환한다.

  2. navigablecontainer유효한 속성 값 (value)을 가진 csp 속성을 가지고 있으면, value를 반환한다.

  3. navigablecontainer documentpolicy containerrequired CSP를 반환한다.

이를 업스트림한다.

3. 암시적 정책 수락

임베디는 응답과 함께 `Allow-CSP-From` 헤더를 반환함으로써 임베더가 지정한 정책 요구사항을 명시적으로 수락할 수 있다. 또한 요구사항은 임베더가 요구한 정책만큼 엄격한 순효과를 가지는 정책(또는 정책 집합)을 포함하는 `Content-Security-Policy` 헤더를 전달함으로써 암시적으로 수락될 수도 있다.

그러나 "최소한 그만큼 엄격하다"는 표현은 그다지 정밀하지 않다. 단순한 경우는 명확하다. 예를 들어 임베더가 object-src https://cdn.example.com을 요구하면, 임베디는 object-src 'none'으로 응답할 수 있다. 전자에 의해 차단될 모든 가능한 리소스는 후자에 의해서도 차단되므로(객체를 전혀 허용하지 않기 때문에), 임베딩을 차단하지 않는다. CSP의 구문적 복잡성은 더 복잡한 경우를 추론하기 다소 어렵게 만든다. 예를 들어 script-src 'unsafe-inline' http: 'sha256-abc...def'가 주어지면, script-src 'unsafe-inline'이 요구된 정책의 부분집합처럼 보일 수 있다. 그러나 hash-source 표현식이 존재한다는 것은 요구된 정책에서 'unsafe-inline'이 무시된다는 뜻이므로, 겉보기와 달리 후자의 정책은 실제로 전자보다 더 많은 것을 허용하게 된다.

여기서는 "최소한 그만큼 엄격하다"라는 개념을 "포섭"이라고 부른다. 하나의 content security policy object (A)는 B가 허용하는 모든 것을 A도 허용하는 경우 다른 객체 (B)를 포섭한다고 한다. 이 경우 AB포섭하거나, BA에 의해 포섭된다.

하지만 항상 단일 정책만 비교하는 것은 아니다. 여러 정책이 CSP list에 존재하는 경우, 이들은 "The effect of multiple policies"에 설명된 결합된 효과를 가진다. 여기서는 CSP list의 결합된 효과를 그들의 교집합이라고 한다. 자세한 내용은 아래 § 3.1 교집합에 명시되어 있다.

교집합이 정의되면, A포섭하는 CSP list라는 것은 A가 그 목록의 교집합포섭하는 경우에만 성립한다고 말할 수 있다.

3.1. 교집합

3.1.1. CSP 목록 교집합

origin (origin)에 대한 CSP list (list)의 교집합은 이들의 순효과를 나타내는 단일 Content Security Policy object이며, 다음 알고리즘으로 생성된다:

참고: 여러 정책의 교집합을 항상 단일 정책으로 표현할 수 있는 것은 아니다. 예를 들어 script-src 'unsafe-inline'script-src 'nonce-abc'를 생각해 보라. 전자는 인라인 스크립트만 허용하고, 후자는 특정 토큰이 있는 인라인 또는 외부화된 스크립트만 허용한다. 순효과(특정 토큰이 있는 인라인 스크립트만 허용)는 단일 정책으로 만들 수 없다. 이러한 정책을 다루는 일은 현재로서는 독자의 연습 문제로 남겨둔다.

독자에게 이 연습을 시켜서는 안 된다. 또한 단일 정책으로 표현할 수 없는 교집합을 처리하는 방법에 대한 지침도 제공해야 한다(예: 정책 목록을 유지하는 방식).

  1. result를 빈 directive set과 "enforce"인 disposition을 가진 content security policy object로 둔다.

  2. list의 각 policy에 대해:

    1. policydisposition이 "report"이면, 계속한다.

    2. resultorigin에 대한 resultpolicy교집합으로 설정한다.

  3. result를 반환한다.

다음 serialized CSP 목록의 각 항목을 파싱하여 생성된 정책들의 교집합은:
«
    "default-src 'self' http://example.com http://example.net; connect-src 'none';",
    "connect-src http://example.com/; script-src http://example.com/",
    "style-src 'self'; script-src http://example.com/ http://example.net",
»

다음 serialized CSP를 파싱하여 생성된 정책이다:

"default-src 'self' http://example.com http://example.net; connect-src 'none'; script-src http://example.com/; style-src 'self'"

초기 목록에 지정된 각 정책은 그 교집합을 포섭한다.

3.1.2. 정책 교집합

origin (origin)에 대한 두 Content Security Policy objects (AB)의 교집합은 이들의 결합된 효과를 나타내는 단일 Content Security Policy object이며, 다음 알고리즘으로 생성된다:

  1. Assert: AB는 모두 "enforce"인 disposition을 가진다.

  2. Adirective set비어 있으면, B를 반환한다.

  3. Bdirective set비어 있으면, A를 반환한다.

  4. policy를 빈 directive set과 "enforce"인 disposition을 가진 새 content security policy object로 둔다.

  5. directive names를 빈 set으로 둔다.

  6. A의 각 directive에 대해:

    1. directivenamedirective names추가한다.

  7. B의 각 directive에 대해:

    1. directivenamedirective names추가한다.

  8. directive names의 각 directive name에 대해:

    1. directive name이 "report-uri", "report-to"이면, 계속한다.

    2. directive Adirective nameA에 대한 유효 지시문 값으로 둔다.

    3. directive Bdirective nameB에 대한 유효 지시문 값으로 둔다.

    4. Assert: directive Adirective B가 모두 null은 아니며, 둘의 values가 모두 source lists이거나, 둘의 values가 모두 source lists가 아니다.

    5. directive A 또는 directive B 중 하나라도 valuesource list가 아니면, 계속한다.

      source list가 아닌 것들을 처리하도록 이 정의를 확장해야 한다. 또한 이에 대해 더 정밀해야 하며, 아마도 directive name에 대해 검사할 수 있는 "source list directive" 같은 용어를 정의해야 할 것이다.

    6. directive Anull이면:

      1. directive를 다음 속성을 가진 새 directive로 둔다:

        name

        directive name

        value

        directive Bvalue

      2. directivepolicydirective set추가한다.

      3. 계속한다.

    7. directive Bnull이면:

      1. directive를 다음 속성을 가진 새 directive로 둔다:

        name

        directive name

        value

        directive Avalue

      2. directivepolicydirective set추가한다.

      3. 계속한다.

    8. directive valuedirective Avalue, directive Bvalue, directive name, 그리고 origin교집합으로 둔다.

    9. directive를 다음 속성을 가진 새 directive로 둔다:

      name

      directive name

      value

      directive value

    10. directivepolicydirective set추가한다.

  9. policy를 반환한다.

다음 serialized CSP를 파싱하여 얻은 정책들의 교집합은:
"default-src 'self' http://example.com http://example.net; connect-src 'none';"

and

"connect-src http://example.com/; script-src http://example.com/"

다음 serialized CSP를 파싱하여 얻은 정책이다:

"default-src 'self' http://example.com http://example.net; connect-src 'none'; script-src http://example.com/;"

주어진 두 정책은 모두 교집합포섭한다. 예를 들어, 그 교집합의 "script-src http://example.com/"은 첫 번째 정책의 "default-src 'self' http://example.com http://example.net"와 두 번째 정책의 "script-src http://example.com/"에 의해 포섭된다.

3.1.3. 소스 목록 교집합

directive name (name)과 origin (origin)에 대한 두 source lists교집합은 이들의 순효과를 나타내는 source list이다. 그러한 source list가 존재하지 않는 경우(예: Ahttps://example.com/Bhttps://not-example.com), 교집합은 목록 « 'none' »가 된다.

  1. effective AA, name, origin에 대한 유효 소스 목록으로 둔다.

  2. effective BB, name, origin에 대한 유효 소스 목록으로 둔다.

  3. effective A 또는 effective B 중 하나라도 « 'none' »이면, « 'none' »를 반환한다.

  4. effective A가 비어 있으면, effective B를 반환한다.

  5. effective B가 비어 있으면, effective A를 반환한다.

  6. schemes를 빈 set으로 둔다.

  7. intersection을 빈 source list로 둔다.

  8. effective B의 각 expression B에 대해:

    1. expression Bscheme-source 문법과 일치하고 effective A포함되어 있으면, expression Bschemes추가한다.

      참고: 위에서 유효 소스 목록을 얻었다는 것은 scheme-source 문법과 일치하는 토큰이 이미 정규화되어 "http:"/"ws:"가 "https:"/"ws:" 없이 나타나는 일이 없다는 뜻이다.

  9. schemes의 각 expression에 대해:

    1. expression이 "https:"와 일치하지 않거나 schemes가 "http:"를 포함하지 않으면:

      1. expression이 "wss:"와 일치하지 않거나 schemes가 "ws:"를 포함하지 않으면, expressionintersection추가한다.

  10. effective A의 각 expression A에 대해:

    1. expression Ascheme-source 문법과 일치하고 schemesexpression A포함하면, 계속한다.

    2. effective B의 각 expression B에 대해:

      1. expression Aexpression B 중 적어도 하나가 scheme-source 또는 host-source 문법과 일치하지 않으면:

        1. expression Akeyword-source 문법과 일치하고 expression BASCII 대소문자 구분 없음으로 일치하면, expression Aintersection추가한다.

        2. expression Anonce-source 또는 hash-source 문법과 일치하고 expression B같으면, expression Aintersection추가한다.

        3. 다음 expression B계속한다.

      2. expression Bscheme-partschemes의 요소 중 하나와 일치하면, 다음 expression B계속한다.

      3. expression Aexpression B교집합null이 아니면, 그 결과를 intersection추가한다.

  11. intersection을 반환한다.

다음 경우에서 intersectionAB에 대한 교집합이다.
A = wss: http://example.com
B = https: wss: 'none'
intersection = wss: https://example.com

표현식 "wss:"는 두 정책 모두에 있으므로, 그들의 교집합에도 존재한다. 마찬가지로, "http://example.com"은 "http://example.com"과 "https:" 모두에 의해 포섭되는 유일한 표현식이므로 교집합에 존재한다. "'none'""은 B의 유일한 토큰이 아니므로 무시된다는 점에 주의하라.

A = http://sub.a.com http://*.b.com
B = https://sub.a.com:* http://*.c.com
intersection = https://sub.a.com

유사한 소스는 두 개뿐이다. A의 "http://sub.a.com"은 B의 "https://sub.a.com:*"와 유사하므로 두 소스 목록의 교집합은 "https://sub.a.com"이다.

A = 'unsafe-inline' http://example.com:443/page1/html 'nonce-abc'
B = 'unsafe-inline' https://example.com:443/ 'strict-dynamic' 'nonce-abc'
intersection = 'nonce-abc'

"strict-dynamic"은 nonce-sourcehash-source 표현식만 인정하므로, B는 사실상 "'strict-dynamic' 'nonce-abc'"이다. 따라서 교집합은 "'nonce-abc'"이다.

3.1.4. 소스 표현식 교집합

source expressionscheme-source 또는 host-source 문법과 일치하는 다른 두 표현식 AB의 더 제한적인 scheme-part, host-part, port-part, 그리고 path-part를 포함하는 경우 그 두 표현식의 교집합이라고 한다.

다음 경우에서 IntersectAB교집합이다.
A = https:
B = http:
Intersect = https:
// http: allows both http: and https:, so https: is the intersection.
A = http://*.example.com
B = https://sub.example.com:*
Intersect = https://sub.example.com:443
// A does not specify a port, so only default ports are allowed.
A = http://example.com:80/page1/html
B = https://example.com:443/
Intersect = null
// A is explicitly locked to port 80, which cannot match B's equally explicit port 443.
A = https:
B = http://example.com
Intersect = https://example.com.
A = https://sub.example.com:*
B = http://*.example.com/page.html
Intersect = https://sub.example.com/page.html
3.1.4.1. scheme-sourcehost-source 교집합
scheme-source 또는 host-source 문법과 일치하는 두 source expressions (AB)가 주어졌을 때, ABsource-expression similar이면 그들의 교집합을 반환한다. 그렇지 않으면 null을 반환한다.
  1. ABsource-expression similar하지 않으면, null을 반환한다.

  2. source를 빈 문자열로 둔다.

  3. scheme AAscheme-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  4. scheme BBscheme-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  5. more secure scheme Bscheme Ascheme Bscheme-part match하지 않으면 true로, 그렇지 않으면 false로 둔다.

  6. scheme Anull이 아니고 more secure scheme Bfalse이면 scheme A와 ":"를 source에 추가한다. 그렇지 않고 scheme Bnull이 아니면 scheme B와 ":"를 source에 추가한다.

  7. AB가 모두 scheme-source 문법과 일치하면, source를 반환한다.

  8. source가 비어 있지 않으면 "//"를 source에 추가한다.

  9. host AAhost-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  10. host BBhost-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  11. host Anull이 아니면:

    1. host Bnull이면, host Asource에 추가한다. 주 알고리즘의 다음 단계로 계속한다.

    2. Ascheme-source 문법과 일치하지 않고 wildcard host를 가지지 않으면, host Asource에 추가한다.

    3. 그렇지 않으면, host Bsource에 추가한다.

  12. host Anull이면, host Bsource에 추가한다.

  13. port AAport-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  14. port BBport-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  15. port Anull이면, port Bnull이 아닌 경우 ":"와 port Bsource에 추가한다.

  16. port Anull이 아니면:

    1. port Bnull이면, ":"와 port Asource에 추가한다. 주 알고리즘의 다음 단계로 계속한다.

    2. Awildcard port를 가지지 않고 more secure scheme Bfalse이면, ":"와 port Asource에 추가한다.

    3. 그렇지 않으면, ":"와 port Bsource에 추가한다.

  17. path AApath-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  18. path BBpath-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  19. path Anull이면, path Bnull이 아닌 경우 path Bsource에 추가한다.

  20. path Anull이 아니면:

    1. path Bnull이면, path Asource에 추가한 결과를 반환한다.

    2. path Apath Bpath-part matches하면, path Asource에 추가한다.

    3. 그렇지 않으면, path Bsource에 추가한다.

  21. source를 반환한다.

3.1.5. 교집합 헬퍼

3.1.5.1. 유효 지시문 값
문자열 (name)과 content security policy object (policy)가 주어졌을 때, namepolicy에 대한 유효 지시문 값은 다음 단계를 실행한 결과인 value이다:
  1. name에 대해 전환하고 관련 단계를 실행한다:

    "child-src"
    "connect-src"
    "font-src"
    "img-src"
    "manifest-src"
    "media-src"
    "object-src"
    "script-src"
    "style-src"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. policydirective set이 "default-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      2. null을 반환한다.

    "script-src-elem"
    "script-src-attr"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. policydirective set이 "script-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      2. policydirective set이 "default-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      3. null을 반환한다.

    "style-src-elem"
    "style-src-attr"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. policydirective set이 "style-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      2. policydirective set이 "default-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      3. null을 반환한다.

    "frame-src"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. policydirective set이 "child-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      2. policydirective set이 "default-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      3. null을 반환한다.

    "worker-src"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. policydirective set이 "child-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      2. policydirective set이 "script-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      3. policydirective set이 "default-src"인 name을 가진 directive포함하면, 그 directivevalue를 반환한다.

      4. null을 반환한다.

    "base-uri"
    "block-all-mixed-content"
    "default-src"
    "frame-ancestors"
    "form-action"
    "plugin-types"
    "report-uri"
    "require-sri-for"
    "sandbox"
    "upgrade-insecure-requests"
    1. policydirective setnamename을 가진 directive포함하면, 그 directivevalue를 반환한다.

      1. null을 반환한다.

  2. null을 반환한다.

3.1.5.2. 유효 소스 목록
source list (list), 문자열 (name), 그리고 origin (origin)이 주어졌을 때, list, name, 그리고 origin에 대한 유효 소스 목록'self'* 같은 복잡한 토큰을 확장하고, 효과가 없거나, 무효화되었거나, 유효하지 않은 토큰(예를 들어 nonce가 있는 경우의 'unsafe-inline')을 제거하는 list의 단순화이다. 다음 단계를 실행한 결과는 일반적으로 list보다 더 길지만, 비교하기는 훨씬 더 간단하다:
  1. list비어 있거나 « 'none' »이면, « 'none' »을 반환한다.

  2. result를 빈 source list로 둔다.

  3. list의 각 expression에 대해:

    1. expression이 "'self'"이면:

      1. origin이 주어졌을 때 § 4.2.1 'self'를 origin에 대한 host-source 표현식으로 다시 쓰기.를 실행한 결과를 result추가한다.

      2. 계속한다.

    2. expressionkeyword-source 문법과 일치하고, name이 "script-src" 또는 "style-src"가 아니면, 계속한다.

    3. 다음 문장 중 하나라도 참이면 계속한다:

    4. expression이 U+002A ASTERISK 문자(*)이면:

      1. « "ftp:", "http:", "https:", "ws:", "wss:" »의 각 scheme에 대해:

        1. schemeresult에 추가한다.

      2. originscheme과 ":"를 연결한 값을 result에 추가한다.

      3. 계속한다.

    5. expressionscheme-source 문법과 일치하면:

      1. expression이 "http:"이면, "https:"를 result추가한다.

      2. expression이 "ws:"이면, "wss:"를 result추가한다.

    6. expressionhost-source 문법과 일치하면:

      1. expressionscheme-part가 "http"이면, "https://", expressionhost-part, expressionport-part, 그리고 expressionpath-part를 연결한 결과를 result에 추가한다.

      2. expressionscheme-part가 "ws"이면, "wss://", expressionhost-part, expressionport-part, 그리고 expressionpath-partresult에 연결한 결과를 추가한다.

    7. expressionresult추가한다.

  4. result비어 있거나 « 'strict-dynamic' »이면, « 'none' »을 반환한다.

  5. result를 반환한다.

origin이 https://example.test/인 임의의 지시문에 대해:

https: wss: 'none' 'self'
유효 소스 목록은 "http: wss: https://example.test/"이다. "'none'"은 유일한 소스가 아닐 때 아무 효과가 없으므로 유효 소스 목록의 일부가 아니라는 점에 유의하라.

"style-src"에 대해:

http://example.com 'strict-dynamic' 'nonce-abc'
유효 소스 목록은 "http://example.com 'nonce-abc'"이다. "'strict-dynamic'"은 "script-src"가 아닌 지시문에서는 무시되기 때문이다.

"script-src"에 대해:

http://example.com 'strict-dynamic' 'nonce-abc'
유효 소스 목록은 "'strict-dynamic' 'nonce-abc'"이다. "script-src"의 경우 "'strict-dynamic'"은 host 및 scheme 소스 표현식을 인정하지 않기 때문이다.
3.1.5.3. 소스 표현식 유사성

source expression (A)은 AB같거나, 또는 문법의 관련 부분이 일치하는 경우(예를 들어 scheme-source 표현식의 경우, 각각의 scheme-part가 어느 한 방향으로 scheme-part match해야 한다), 다른 source expression (B)과 source-expression similar하다고 한다.

참고: 이 속성은 대칭적이다. 즉 ABsource-expression similar하면, B 역시 Asource-expression similar하다.

source expressionhost-part의 첫 번째 문자가 U+002A ASTERISK 문자(*)인 경우, 그 source expressionwildcard host를 가진다.

source expressionport-part가 U+002A ASTERISK 문자(*)인 경우, 그 source expressionwildcard port를 가진다.

  1. A의 문법이 B의 문법과 일치하지 않으면, "Not Similar"를 반환한다.

  2. Akeyword-source, nonce-source, 또는 hash-source 문법과 일치하면:

    1. AB같으면, "Similar"를 반환한다.

    2. "Not Similar"를 반환한다.

  3. scheme AAscheme-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  4. scheme BBscheme-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  5. scheme Ascheme Bscheme-part match하지 않고, scheme Bscheme Ascheme-part match하지 않으면, "Not Similar"를 반환한다.

  6. A 또는 Bscheme-source 문법과 일치하면, "Similar"를 반환한다.

  7. host AAhost-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  8. host BBhost-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  9. port AAport-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  10. port BBport-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  11. path AApath-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  12. path BBpath-part(존재하는 경우)로, 그렇지 않으면 null로 둔다.

  13. 다음 중 하나라도 참이면 "Not Similar"를 반환한다:

    1. AB가 모두 wildcard host를 가지지만, host Ahost BASCII 대소문자 구분 없음으로 일치하지 않는다.

    2. AB 중 최대 하나만 wildcard host를 가지고, host Ahost Bhost-part match하지 않으며, host Bhost Ahost-part match하지 않는다.

    3. AB 모두 wildcard port를 가지지 않고, port Aport Bport-part match하지 않으며, port Bport Aport-part match하지 않는다.

    4. path Apath Bpath-part match하지 않고, path Bpath Apath-part match하지 않는다.

  14. "Similar"를 반환한다.

A = 'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'
B = 'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'

AB가 모두 nonce-source 문법과 일치하고 AB같으므로, AB와 유사하다.

A = https://inner.example.com/foo/
B = http://*.example.com/foo/bar/

Awildcard host를 가지므로, 이 경우 "inner"인 모든 하위 도메인과 일치한다. 따라서 AB와 유사하다.

A = http://*.example.com
B = https://inner.example.com:*

AB의 포트가 서로 다르더라도, "http"가 "http"와 더 안전한 변형인 "https" 모두와 일치하므로 AB는 유사하다.

A = http://example.com:80/page1/html
B = https://example.com:443/

AB가 서로 다른 포트를 명시적으로 지정하므로, AB와 유사하지 않다.

A = 'sha256-abc123'
B = 'sha512-cde456'

AB가 모두 hash-source 문법과 일치하더라도, 해시가 일치하지 않으므로 AB와 일치하지 않는다.

A = http://example.com:80
B = http://example.com:334

이 경우 AB의 포트가 일치하지 않으므로, 두 소스는 유사하지 않다.

A = http://example.com/page.html
B = http://example.com/index.html

두 소스는 경로가 일치하지 않으므로 유사하지 않다.

나머지 교집합 알고리즘을 이 절로 옮긴다.

3.2. 포섭

3.2.1. CSP 목록 포섭

content security policy object subsuming policy와 그 origin (subsuming origin), 그리고 목록content security policy object 객체들 policy list와 그 origin (origin)이 주어졌을 때, 이 알고리즘은 subsuming policypolicy list포섭하면 "Subsumes"를 반환하고, 그렇지 않으면 "Does Not Subsume"를 반환한다.
  1. subsuming policynull이면, "Subsumes"를 반환한다.

  2. subsuming policydisposition이 "report"이면, "Subsumes"를 반환한다.

  3. subsuming policydirective set비어 있으면, "Subsumes"를 반환한다.

  4. policy listis empty이거나 null이면, "Does Not Subsume"를 반환한다.

  5. effective policypolicy listorigin이 주어졌을 때 § 3.1.1 CSP 목록 교집합을 실행한 결과로 둔다.

  6. subsuming policy, subsuming origin, effective policy, 그리고 origin이 주어졌을 때 § 3.2.2 정책 포섭을 실행한 결과를 반환한다.

3.2.2. 정책 포섭

content security policy object A와 그 origin (origin A), 그리고 content security policy object B와 그 origin (origin B)이 주어졌을 때, 이 알고리즘은 AB포섭하면 "Subsumes"를 반환하고, 그렇지 않으면 "Does Not Subsume"를 반환한다.
  1. Adirective set비어 있으면, "Subsumes"를 반환한다.

  2. Adirective set에 있는 각 directive A에 대해:

    1. directive namedirective Aname으로 둔다.

    2. directive name이 "default-src", "report-uri", "report-to"이면, 계속한다.

    3. effective directive Adirective nameA에 대한 유효 지시문 값으로 둔다.

    4. effective directive Bdirective nameB에 대한 유효 지시문 값으로 둔다.

    5. effective directive Anull이면, 계속한다.

    6. effective directive Bnull이면, "Does Not Subsume"를 반환한다.

    7. directive Aname이 "frame-ancestors"이면:

      1. effective directive B가 « "'none'" »이면, 계속한다.

      2. effective directive A가 « "'none'" »이면, "Does Not Subsume"를 반환한다.

      3. effective directive B의 각 expression B에 대해:

        1. found matchfalse로 둔다.

        2. effective directive A의 각 expression A에 대해:

          1. expression Aexpression B가 주어졌을 때 § 3.2.4 소스 표현식 포섭이 "Subsumes"를 반환하면, found matchtrue로 설정한다. 이 내부 루프에서 빠져나온다.

        3. found matchfalse이면, "Does Not Subsume"를 반환한다.

    8. directive Aname이 "plugin-types"이면:

      1. effective directive B의 각 type B에 대해:

        1. effective directive Atype B포함하지 않으면, "Does Not Subsume"를 반환한다.

    9. directive Aname이 "sandbox"이면:

      1. flags Aeffective directive A가 주어졌을 때 sandboxing directive 파싱의 결과로 둔다.

      2. flags Beffective directive B가 주어졌을 때 sandboxing directive 파싱의 결과로 둔다.

      3. flags A의 각 flag에 대해:

        1. flags Bflag포함하지 않으면, "Does Not Subsume"를 반환한다.

      참고: 정책 $A$는 $B$가 더 제한적인 경우 $B$를 포섭한다. sandbox 플래그의 경우, 이는 $A$가 허용하는 모든 권한이 $B$에서도 허용되어야 함을 의미한다. $B$가 $A$에 포함된 플래그를 생략하면, $B$는 해당 특정 권한에 대해 최소한 $A$만큼 제한적이지 않다.

    10. directive Aname이 "disown-opener"이면, 계속한다.

    11. 그렇지 않으면:

      1. effective directive A, origin A, directive name, effective directive B, origin B, 그리고 directive name이 주어졌을 때 § 3.2.3 소스 목록 포섭을 실행한 결과가 "Does Not Subsume"이면, "Does Not Subsume"를 반환한다.

  3. "Subsumes"를 반환한다.

3.2.3. 소스 목록 포섭

source list A와 그 origin (origin A) 및 문자열 (directive A), 그리고 source list B와 그 origin (origin B) 및 문자열 (directive B)이 주어졌을 때, 이 알고리즘은 AB포섭하면 "Subsumes"를 반환하고, 그렇지 않으면 "Does Not Subsume"를 반환한다.

directive는 그 표현식이 자신의 value포함되어 있으면, 주어진 source expression포함한다.

  1. directive Adirective BASCII 대소문자 구분 없음으로 일치하지 않으면, "Does Not Subsume"를 반환한다.

  2. A가 비어 있거나 Bnone이면, "Subsumes"를 반환한다.

  3. B가 비어 있거나 Anone이면, "Does Not Subsume"를 반환한다.

  4. directive B가 "script-src"이고 Bkeyword-source 표현식 "strict-dynamic"을 포함하지만 A는 이를 포함하지 않으면, "Does Not Subsume"를 반환한다.

  5. directive B가 "script-src" 또는 "style-src"이면:

    1. Bkeyword-source 표현식 "unsafe-eval"을 포함하지만 A는 이를 포함하지 않으면, "Does Not Subsume"를 반환한다.

    2. Bkeyword-source 표현식 "unsafe-hashed-attributes"를 포함하지만 A는 이를 포함하지 않으면, "Does Not Subsume"를 반환한다.

    3. type Bdirective B가 "script-src"이면 "script", 그렇지 않으면 "style"로 둔다. 마찬가지로, type Adirective A가 "script-src"이면 "script", 그렇지 않으면 "style"로 둔다.

    4. Btype B가 주어졌을 때 Content Security Policy 3 § 6.7.3.2 Does a source list allow all inline behavior for type?가 "Allows"를 반환하지만, Atype A가 주어졌을 때 "Does Not Allow"를 반환하면, "Does Not Subsume"를 반환한다.

  6. list Alist B를 빈 목록으로 둔다.

  7. A의 각 expression A에 대해:

    1. expression A가 "self"이면, origin A가 주어졌을 때 § 4.2.1 'self'를 origin에 대한 host-source 표현식으로 다시 쓰기.가 반환한 host-sourcelist A에 추가한다.

    2. expression A가 U+002A ASTERISK 문자(*)와 일치하면, 다음 scheme-source 표현식들을 list A에 추가한다: "ftp:", "http:", "https:", "ws:", "wss:", 그리고 origin Ascheme.

      1. directive A가 "img-src" 또는 "media-src"이면, scheme-source 표현식 "data:"를 list A에 추가한다.

      2. directive A가 "media-src"이면, scheme-source 표현식 "blob:"을 list A에 추가한다.

      3. 다음 expression A계속한다.

    3. expression Akeyword-source 문법과 일치하지 않으면, expression Alist A에 추가한다.

  8. B의 각 expression B에 대해:

    1. expression B가 "self"이면, origin B가 주어졌을 때 § 4.2.1 'self'를 origin에 대한 host-source 표현식으로 다시 쓰기.가 반환한 host-sourcelist B에 추가한다.

    2. expression B가 U+002A ASTERISK 문자(*)와 일치하면, 다음 scheme-source 표현식들을 list B에 추가한다: "ftp:", "http:", "https:", "ws:", "wss:", 그리고 origin Bscheme.

      1. directive B가 "img-src" 또는 "media-src"이면, scheme-source 표현식 "data:"를 list B에 추가한다.

      2. directive B가 "media-src"이면, scheme-source 표현식 "blob:"을 list B에 추가한다.

      3. 다음 expression B계속한다.

    3. expression Bkeyword-source 문법과 일치하지 않으면, expression Blist B에 추가한다.

  9. list B가 비어 있으면, "Subsumes"를 반환한다.

  10. list A가 비어 있으면, "Does Not Subsume"를 반환한다.

  11. list B의 각 expression B에 대해:

    1. expression Bhash-source 문법 또는 nonce-source 문법과 일치하면, directive A가 "script-src" 또는 "style-src"가 아닌 한 다음 expression으로 계속한다.

    2. found matchfalse로 둔다.

    3. list A의 각 expression A에 대해:

      1. expression Aexpression B가 주어졌을 때 § 3.2.4 소스 표현식 포섭이 "Subsumes"를 반환하면, found matchtrue로 설정한다. 이 내부 루프에서 빠져나온다.

    4. found matchfalse이면, "Does Not Subsume"를 반환한다.

  12. "Subsumes"를 반환한다.

directive Adirective B를 "script-src"로 둔다. 다음 예제를 고려하라:
A = "http://example.com 'sha256-xzi4zkCjuC8'"
B = "http://example.com"

Bhash-source 표현식을 허용하지 않지만, 그 값이 A에서 발견되므로, AB를 포섭한다. 그러나 BA포섭한다는 것은 참이 아니다.

A = "https://example.com 'sha256-xzi4zkCjuC8'"
B = "http://example.com"

이 경우 "https://example.com"은 "http://example.com"을 포섭하지 않으므로, AB를 포섭하지 않는다.

A = "http://example.com 'sha256-xzi4zkCjuC8'"
B = "http://example.com 'unsafe-inline'"

B모든 인라인 동작을 허용하지만 A는 그렇지 않으므로, AB포섭하지 않는다.

A = "http://example.com 'sha256-xzi4zkCjuC8' 'strict-dynamic'"
B = "http://example.com 'unsafe-inline' 'strict-dynamic'"

AB 모두 모든 인라인 동작을 허용하지 않는다. 이 경우 AB포섭한다.

3.2.4. 소스 표현식 포섭

source expressions AB가 주어졌을 때, 이 알고리즘은 AB포섭하면 "Subsumes"를 반환하고, 그렇지 않으면 "Does Not Subsume"를 반환한다.
  1. Assert: AB는 둘 다 keyword-source 문법과 일치하지 않는다.

  2. AB가 모두 host-source 또는 scheme-source 문법과 일치하면:

    1. Ascheme-part (또는 Ascheme-part를 포함하지 않으면 null)와 Bscheme-part (또는 Bscheme-part를 포함하지 않으면 null)가 주어졌을 때 Content Security Policy 3 § 6.7.2.9 scheme-part matching이 "Does Not Match"를 반환하면, "Does Not Subsume"를 반환한다.

    2. A 또는 Bscheme-source 문법과 일치하면:

      1. Ascheme-source 문법과 일치하면, "Subsumes"를 반환한다. 그렇지 않으면, "Does Not Subsume"를 반환한다.

    3. Bwildcard host를 가지면:

      1. Awildcard host를 가지지 않으면, "Does not Subsume"를 반환한다.

      2. remaining host BBhost-part에서 선행 ("*.") 을 제거한 결과로 둔다.

      3. Ahost-partremaining host B가 주어졌을 때 Content Security Policy 3 § 6.7.2.10 host-part matching이 "Does Not Match"를 반환하면, "Does Not Subsume"를 반환한다.

    4. Bwildcard host를 가지지 않고, Ahost-partBhost-part가 주어졌을 때 Content Security Policy 3 § 6.7.2.10 host-part matching이 "Does Not Match"를 반환하면, "Does Not Subsume"를 반환한다.

    5. Bwildcard port를 가지지만 Awildcard port를 가지지 않으면, "Does Not Subsume"를 반환한다.

    6. Bwildcard port를 가지지 않고, Aport-part (또는 Aport-part를 포함하지 않으면 null)와 Bport-part (또는 Bport-part를 포함하지 않으면 null)가 주어졌을 때 Content Security Policy 3 § 6.7.2.11 port-part matching이 "Does Not Match"를 반환하면, "Does Not Subsume"를 반환한다.

    7. Apath-part (또는 Apath-part를 포함하지 않으면 null)와 Bpath-part (또는 Bpath-part를 포함하지 않으면 null)가 주어졌을 때 Content Security Policy 3 § 6.7.2.12 path-part matching이 "Does Not Match"를 반환하면, "Does Not Subsume"를 반환한다.

    8. "Subsumes"를 반환한다.

  3. AB가 모두 hash-source 문법과 일치하면:

    1. AB같으면, "Subsumes"를 반환한다. 그렇지 않으면 "Does Not Subsume"를 반환한다.

  4. AB가 모두 nonce-source 문법과 일치하면:

    1. "Subsumes"를 반환한다.

    참고: Nonce source 일치는 악의적인 임베더가 § 6.1 정책 누출에 설명된 공격으로 nonce 값을 무차별 대입하지 못하도록 값에 무관하다.

  5. "Does Not Subsume"를 반환한다.

nonce와 hash에 대한 포섭은 ('self' 또는 '*'와 'unsafe-inline'이 결합된 것처럼) 더 허용적인 소스가 논리적으로 이들을 포섭하는 경우를 고려하도록 갱신되어야 한다.

4. 알고리즘

4.1. request에 대한 responserequiredCSP에 의해 차단되는가?

response (response), request (request), 그리고 serialized CSP-또는-null (requiredCSP)이 주어졌을 때, 이 알고리즘은 적절하게 "Allowed" 또는 "Blocked"를 반환한다:

  1. requiredCSPnull이면 "Allowed"를 반환한다.

  2. required policyrequiredCSP를 "enforce"로 파싱한 결과로 둔다.

  3. responserequest에 대해 실행했을 때 § 4.2 response는 request에서 온 정책의 포괄적 시행을 허용하는가? 알고리즘이 "Allowed"를 반환하면, "Allowed"를 반환한다.

  4. required policy, responseurlorigin, response의 Content Security Policies를 파싱한 결과, 그리고 responseurlorigin에 대해 실행했을 때 § 3.2.1 CSP 목록 포섭 알고리즘이 "Subsumes"를 반환하면, "Allowed"를 반환한다.

  5. "Blocked"를 반환한다.

4.2. responserequest에서 온 정책의 포괄적 시행을 허용하는가?

response (response)와 request (request)가 주어졌을 때, 이 알고리즘은 전자가 후자에게 임의의 정책을 시행하도록 허용하면 "Allowed"를 반환하고, 그렇지 않으면 "Not Allowed"를 반환한다:

  1. responseurlschemelocal scheme이면, "Allowed"를 반환한다.

    참고: local scheme 응답은 이미 임베더에서 정책을 상속하므로, 이 임베딩 메커니즘을 통해 임베더가 해당 정책을 더 강화하도록 허용한다.

  2. responseheader list에 `Allow-CSP-From`라는 이름의 헤더(header)가 있으면:

    1. header의 값이 "*"이면, "Allowed"를 반환한다.

    2. requestorigin직렬화하고 UTF-8 인코딩한 값이 header의 값이면, "Allowed"를 반환한다.

  3. "Not Allowed"를 반환한다.

4.2.1. 'self'origin에 대한 host-source 표현식으로 다시 쓴다.

origin (origin)이 주어졌을 때, 이 알고리즘은 해당 origin에 대해 'self'와 동일한 효과를 가지는 host-source 표현식을 반환한다:

  1. originopaque origin이면, 빈 문자열을 반환한다.

  2. originASCII serialization을 반환한다.

5. 보안 고려사항

5.1. 위협 모델

이 제안은 문서가 자신이 임베드하는 자식 프레임에서 사용되는 콘텐츠를 제어할 수 있게 하는 것을 목표로 한다. 프레임은 일반적으로 그 자체로 보안 경계로 간주되며, cross-origin 접근을 의도적으로 제한하므로, 우리는 그 경계를 약화하지 않도록 해야 한다.

따라서 우리의 목표는 다음과 같다:

이 제안은 CSP의 frame-ancestorsX-Frame-Options 같은 기존 격리 메커니즘을 대체하려는 것이 아니며, 임베디에게 iframe 요소가 이미 나타내는 것 이상의 보호를 제공하지도 않는다.

5.2. 정책 시행

임베드된 문서는 제안된 콘텐츠 보안 정책을 신중하게 평가해야 하며, 임베더가 제안하는 정책을 단순히 반사해서는 안 된다. 그렇게 하면 영리한 공격자가 웹사이트 자체 보호에 필수적인 코드 일부를 선택적으로 비활성화할 수 있게 될 수 있다.

특히, 임베드될 것을 예상하지 않는 문서는 그러한 요청에 대해 계속해서 적절한 frame-ancestors 지시문을 포함하는 콘텐츠 보안 정책으로 응답해야 한다.

5.3. 헤더 반사

서버는 `Sec-Required-CSP` 헤더를 `Content-Security-Policy` 응답 헤더로 무조건 반사하는 것을 주의해야 한다. 부과된 정책은 결과 컨텍스트를 예상치 못한 방식으로 제한하거나, 서버가 달리 적용했을 정책보다 약할 수 있기 때문이다.

대신, 개발자는 신뢰할 수 있는 출처에 대해 `Allow-CSP-From` 헤더를 전달하여 수신 정책을 수락하기 전에 평가하는 것이 권장된다. 이렇게 하면 페이지가 적용하려는 정책은 적용되며, 그 위에 요구된 정책이 계층화된다. 여러 정책은 제한을 더 강화할 수밖에 없으므로, 이는 서버의 정책이 견고한 기준 보호로 유지되도록 보장한다.

5.4. 헤더 길이

이 기능은 임베더가 cross-origin 임베드 문서 요청에 대한 `Sec-Required-CSP` HTTP 헤더의 값을 제어할 수 있게 한다. 서버가 HTTP 헤더 길이에 제한을 적용하는 경우, 이는 네트워크 오류를 일으킬 수 있다. 공격자는 이를 악용하여 캐시 무효화를 강제할 수 있다. 다음을 보라: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events. 이 때문에 유효한 csp 속성의 최대 길이를 4KB로 제한한다.

6. 프라이버시 고려사항

6.1. 정책 누출

시행 메커니즘은 악의적인 임베더가 제약을 무차별 대입하여 페이지의 정책을 cross-origin으로 읽을 수 있게 한다. 정책에 비밀 토큰이나 사용자 이름이 포함되어 있다면, 이는 페이지나 페이지를 로드하는 사용자에 대한 흥미로운 데이터를 누출할 수 있다.

여기서도 최선의 방어는 적절한 frame-ancestors 지시문을 통해 주어진 리소스를 임베드할 수 있는 컨텍스트를 제어하는 것이다.

6.2. 데이터 유출

이 기능은 임베더가 `Sec-Required-CSP` HTTP 헤더를 통해 제3자 엔드포인트로 정보를 보낼 수 있게 한다. 이는 HTTP 요청 자체(GET 매개변수 등)를 통해 터널링할 수 없는 정보를 노출하는 것으로 보이지 않으며, 임베더는 적절한 child-src 지시문이 있는 콘텐츠 보안 정책을 시행함으로써 그러한 요청이 이루어질 수 있는 엔드포인트를 계속 제어한다.

7. 작성 고려사항

7.1. 'self' 요구하기

required CSP를 처리할 때, 키워드 'self'는 정책을 요구한 문서의 origin이 아니라, child navigable에 로드되는 URL의 origin을 가리킨다.

MegaCorp Inc.는 https://example.com/page.html의 페이지에서 'self'를 포함하는 정책을 요구한다:
<iframe src="https://advertisements-r-us.example.com/ad1.cfm"
        csp="script-src 'self'">
</iframe>

반환된 CSP가 다음과 같다면:

Content-Security-Policy: script-src 'self'

그러면 이 iframe 요소는 로드된다.

그러나 반환된 CSP가 다음과 같다면:

Content-Security-Policy: script-src "https://example.com/"

그러면 이 iframe 요소는 로드되지 않는다.

8. IANA 고려사항

영구 메시지 헤더 필드 레지스트리는 `Sec-Required-CSP` 헤더에 대한 다음 등록으로 갱신되어야 한다: [RFC3864]

헤더 필드 이름

Sec-Required-CSP

적용 가능한 프로토콜

http

상태

standard

작성자/변경 관리자

W3C

명세 문서

이 명세 (§ 2.2 Sec-Required-CSP HTTP 요청 헤더 참조)

마찬가지로, 레지스트리는 `Allow-CSP-From` 헤더에 대한 다음 등록으로 갱신되어야 한다: [RFC3864]

헤더 필드 이름

Allow-CSP-From

적용 가능한 프로토콜

http

상태

standard

작성자/변경 관리자

W3C

명세 문서

이 명세 (§ 2.3 Allow-CSP-From HTTP 응답 헤더 참조)

적합성

문서 규약

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

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

이 명세의 예제는 “예를 들어”라는 말로 소개되거나 규범적 텍스트와 구분되도록 class="example"으로 따로 표시된다. 다음과 같다:

이는 정보 제공용 예제의 한 예이다.

정보 제공용 참고는 “참고”라는 말로 시작하며 규범적 텍스트와 구분되도록 class="note"로 따로 표시된다. 다음과 같다:

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

적합한 알고리즘

알고리즘의 일부로 명령형으로 표현된 요구사항 (예: "선행 공백 문자를 모두 제거한다" 또는 "false를 반환하고 이 단계를 중단한다")은 그 알고리즘을 소개할 때 사용된 핵심 단어 ("must", "should", "may" 등)의 의미로 해석되어야 한다.

알고리즘 또는 특정 단계로 표현된 적합성 요구사항은 최종 결과가 동등하기만 하다면 어떤 방식으로든 구현할 수 있다. 특히, 이 명세에 정의된 알고리즘은 이해하기 쉽도록 의도된 것이며 성능을 목적으로 하지 않는다. 구현자는 최적화하는 것이 권장된다.

색인

이 명세에서 정의한 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. 2026년 5월 5일. WD. URL: https://www.w3.org/TR/CSP3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.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/
[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
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul. Registration Procedures for Message Header Fields. 2004년 9월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. 2008년 1월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[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/

IDL 색인

partial interface HTMLIFrameElement {
  [CEReactions] attribute DOMString csp;
};

이슈 색인

이를 모든 HTML로 업스트림한다.
이를 업스트림한다.
독자에게 이 연습을 시켜서는 안 된다. 또한 단일 정책으로 표현할 수 없는 교집합을 처리하는 방법에 대한 지침도 제공해야 한다(예: 정책 목록을 유지하는 방식).
source list가 아닌 것들을 처리하도록 이 정의를 확장해야 한다. 또한 이에 대해 더 정밀해야 하며, 아마도 directive name에 대해 검사할 수 있는 "source list directive" 같은 용어를 정의해야 할 것이다.
나머지 교집합 알고리즘을 이 절로 옮긴다.
nonce와 hash에 대한 포섭은 ('self' 또는 '*'와 'unsafe-inline'이 결합된 것처럼) 더 허용적인 소스가 논리적으로 이들을 포섭하는 경우를 고려하도록 갱신되어야 한다.
MDN

HTMLIFrameElement/csp

In only one current engine.

FirefoxNoneSafariNoneChrome61+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?