테스트
- DOMParser-parseFromString-regression.html (실시간 테스트) (소스)
- DOMParser-parseFromString.html (실시간 테스트) (소스)
- DedicatedWorker-block-eval-function-constructor.html (실시간 테스트) (소스)
- DedicatedWorker-constructor-from-DedicatedWorker.html (실시간 테스트) (소스)
- DedicatedWorker-constructor-from-SharedWorker.html (실시간 테스트) (소스)
- DedicatedWorker-constructor.https.html (실시간 테스트) (소스)
- DedicatedWorker-eval.html (실시간 테스트) (소스)
- DedicatedWorker-importScripts.html (실시간 테스트) (소스)
- DedicatedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- Document-execCommand.html (실시간 테스트) (소스)
- Document-write-appending-line-feed.html (실시간 테스트) (소스)
- Document-write-exception-order.xhtml (실시간 테스트) (소스)
- Document-write.html (live test) (소스)
- Element-insertAdjacentHTML.html (실시간 테스트) (소스)
- Element-outerHTML.html (live test) (소스)
- Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-TT-realm.html (실시간 테스트) (소스)
- Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html (실시간 테스트) (소스)
- Element-setAttribute.html (실시간 테스트) (소스)
- Element-setAttributeNS.html (실시간 테스트) (소스)
- Element-toggleAttribute.html (실시간 테스트) (소스)
- GlobalEventHandlers-onclick.html (실시간 테스트) (소스)
- HTMLElement-generic.html (live test) (소스)
- HTMLScriptElement-in-xhtml-document.tentative.https.xhtml (실시간 테스트) (소스)
- HTMLScriptElement-internal-slot.html (실시간 테스트) (소스)
- Node-multiple-arguments-tt-enforced.html (실시간 테스트) (소스)
- Node-multiple-arguments.html (실시간 테스트) (소스)
- Range-createContextualFragment.html (실시간 테스트) (소스)
- SVGScriptElement-internal-slot.html (실시간 테스트) (소스)
- ServiceWorker-block-eval-function-constructor.https.html (실시간 테스트) (소스)
- ServiceWorker-eval.https.html (실시간 테스트) (소스)
- ServiceWorker-importScripts.https.html (실시간 테스트) (소스)
- ServiceWorkerContainer-register-from-DedicatedWorker.https.html (실시간 테스트) (소스)
- ServiceWorkerContainer-register-from-ServiceWorker.https.html (실시간 테스트) (소스)
- ServiceWorkerContainer-register-from-SharedWorker.https.html (실시간 테스트) (소스)
- ServiceWorkerContainer-register.https.html (실시간 테스트) (소스)
- SharedWorker-block-eval-function-constructor.html (실시간 테스트) (소스)
- SharedWorker-constructor.https.html (실시간 테스트) (소스)
- SharedWorker-eval.html (live test) (소스)
- SharedWorker-importScripts.html (실시간 테스트) (소스)
- SharedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- TrustedType-AttributeNodes.html (실시간 테스트) (소스)
- TrustedTypePolicy-CSP-no-name.html (실시간 테스트) (소스)
- TrustedTypePolicy-CSP-wildcard.html (실시간 테스트) (소스)
- TrustedTypePolicy-createXXX.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-constants.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-createXYZTests.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-noNamesGiven.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-none-name.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-none.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-none.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests-wildcard.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-cspTests.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-non-tt-policy-name.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-createPolicy-unenforced.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-defaultPolicy.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-getAttributeType-namespace.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-getAttributeType-svg.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-getAttributeType.html (실시간 테스트) (소스)
- TrustedTypePolicyFactory-isXXX.html (실시간 테스트) (소스)
- Window-TrustedTypes.html (live test) (소스)
- Window-block-eval-function-constructor.html (실시간 테스트) (소스)
- Window-setTimeout-setInterval.html (실시간 테스트) (소스)
- block-Document-execCommand.html (실시간 테스트) (소스)
- block-string-assignment-to-DOMParser-parseFromString.html (실시간 테스트) (소스)
- block-string-assignment-to-DedicatedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- block-string-assignment-to-Document-parseHTMLUnsafe.html (실시간 테스트) (소스)
- block-string-assignment-to-Document-write.html (실시간 테스트) (소스)
- block-string-assignment-to-Element-insertAdjacentHTML.html (실시간 테스트) (소스)
- block-string-assignment-to-Element-outerHTML.html (실시간 테스트) (소스)
- block-string-assignment-to-Element-setAttribute.html (실시간 테스트) (소스)
- block-string-assignment-to-Element-setAttributeNS.html (실시간 테스트) (소스)
- block-string-assignment-to-Element-setHTMLUnsafe.html (실시간 테스트) (소스)
- block-string-assignment-to-HTMLElement-generic.html (실시간 테스트) (소스)
- block-string-assignment-to-HTMLIFrameElement-srcdoc.html (실시간 테스트) (소스)
- block-string-assignment-to-Range-createContextualFragment.html (실시간 테스트) (소스)
- block-string-assignment-to-ShadowRoot-innerHTML.html (실시간 테스트) (소스)
- block-string-assignment-to-ShadowRoot-setHTMLUnsafe.html (실시간 테스트) (소스)
- block-string-assignment-to-SharedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- block-string-assignment-to-Window-setTimeout-setInterval.html (실시간 테스트) (소스)
- block-string-assignment-to-attribute-via-attribute-node.html (실시간 테스트) (소스)
- block-string-assignment-to-text-and-url-sinks.html (실시간 테스트) (소스)
- block-text-node-insertion-into-script-element.html (실시간 테스트) (소스)
- block-text-node-insertion-into-svg-script-element.html (실시간 테스트) (소스)
- csp-block-eval.html (live test) (소스)
- default-policy-callback-arguments.html (실시간 테스트) (소스)
- default-policy-report-only.html (실시간 테스트) (소스)
- default-policy.html (live test) (소스)
- empty-default-policy-report-only.html (실시간 테스트) (소스)
- empty-default-policy.html (실시간 테스트) (소스)
- eval-csp-no-tt.html (live test) (소스)
- eval-csp-tt-default-policy-mutate.html (실시간 테스트) (소스)
- eval-csp-tt-default-policy.html (실시간 테스트) (소스)
- eval-csp-tt-no-default-policy.html (실시간 테스트) (소스)
- eval-function-constructor-untrusted-arguments-and-applying-default-policy.html (실시간 테스트) (소스)
- eval-function-constructor-untrusted-arguments-and-default-policy-throwing.html (실시간 테스트) (소스)
- eval-function-constructor.html (실시간 테스트) (소스)
- eval-no-csp-no-tt-default-policy.html (실시간 테스트) (소스)
- eval-no-csp-no-tt.html (live test) (소스)
- eval-with-permissive-csp.html (실시간 테스트) (소스)
- get-trusted-types-compliant-attribute-value.html (실시간 테스트) (소스)
- idlharness.window.js (live test) (소스)
- inheriting-csp-for-local-schemes.html (실시간 테스트) (소스)
- legacy-trusted-script-urls.html (실시간 테스트) (소스)
- legacy-trusted-scripts.html (실시간 테스트) (소스)
- modify-attributes-in-callback.html (실시간 테스트) (소스)
- no-require-trusted-types-for-report-only.html (실시간 테스트) (소스)
- no-require-trusted-types-for.html (실시간 테스트) (소스)
- require-trusted-types-for-TypeError-belongs-to-the-global-object-realm.html (실시간 테스트) (소스)
- require-trusted-types-for-report-only.html (실시간 테스트) (소스)
- require-trusted-types-for.html (실시간 테스트) (소스)
- script-enforcement-001-outerHTML.xhtml (실시간 테스트) (소스)
- script-enforcement-001.html (실시간 테스트) (소스)
- script-enforcement-002-outerHTML.xhtml (실시간 테스트) (소스)
- script-enforcement-002.html (실시간 테스트) (소스)
- script-enforcement-003.html (실시간 테스트) (소스)
- script-enforcement-004.html (실시간 테스트) (소스)
- script-enforcement-005.html (실시간 테스트) (소스)
- script-enforcement-006.html (실시간 테스트) (소스)
- script-enforcement-007.html (실시간 테스트) (소스)
- script-enforcement-008.https.html (실시간 테스트) (소스)
- script-enforcement-009.https.html (실시간 테스트) (소스)
- script-enforcement-010.html (실시간 테스트) (소스)
- script-enforcement-011.html (실시간 테스트) (소스)
- set-attributes-no-require-trusted-types.html (실시간 테스트) (소스)
- set-attributes-require-trusted-types-default-policy.html (실시간 테스트) (소스)
- set-attributes-require-trusted-types-no-default-policy.html (실시간 테스트) (소스)
- should-sink-type-mismatch-violation-be-blocked-by-csp-001.html (실시간 테스트) (소스)
- should-sink-type-mismatch-violation-be-blocked-by-csp-002-worker.html (실시간 테스트) (소스)
- should-sink-type-mismatch-violation-be-blocked-by-csp-003.html (실시간 테스트) (소스)
- should-trusted-type-policy-creation-be-blocked-by-csp-001.html (실시간 테스트) (소스)
- should-trusted-type-policy-creation-be-blocked-by-csp-002.html (실시간 테스트) (소스)
- should-trusted-type-policy-creation-be-blocked-by-csp-003.html (실시간 테스트) (소스)
- should-trusted-type-policy-creation-be-blocked-by-csp-004-worker.html (실시간 테스트) (소스)
- should-trusted-type-policy-creation-be-blocked-by-csp-005.html (실시간 테스트) (소스)
- trusted-types-createHTMLDocument.html (실시간 테스트) (소스)
- trusted-types-duplicate-names-list-report-only.html (실시간 테스트) (소스)
- trusted-types-duplicate-names-list.html (실시간 테스트) (소스)
- trusted-types-duplicate-names-without-enforcement.html (실시간 테스트) (소스)
- trusted-types-duplicate-names.html (실시간 테스트) (소스)
- trusted-types-eval-reporting-no-unsafe-eval.html (실시간 테스트) (소스)
- trusted-types-eval-reporting-report-only.html (실시간 테스트) (소스)
- trusted-types-event-handlers.html (실시간 테스트) (소스)
- trusted-types-navigation.html (실시간 테스트) (소스)
- trusted-types-report-only.html (실시간 테스트) (소스)
- trusted-types-reporting-check-report-DedicatedWorker-create-policy.html (실시간 테스트) (소스)
- trusted-types-reporting-check-report-DedicatedWorker-sink-mismatch.html (실시간 테스트) (소스)
- trusted-types-reporting-check-report-Window-create-policy.html (실시간 테스트) (소스)
- trusted-types-reporting-check-report-Window-sink-mismatch.html (실시간 테스트) (소스)
- trusted-types-reporting-clipping-of-sample.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DOMParser-parseFromString.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-ServiceWorkerContainer-register.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-eval.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-function-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-importScripts.html (실시간 테스트) (소스)
- trusted-types-reporting-for-DedicatedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Document-execCommand.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Document-parseHTMLUnsafe.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Document-write.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Element-innerHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Element-insertAdjacentHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Element-outerHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Element-setAttribute.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Element-setHTMLUnsafe.html (실시간 테스트) (소스)
- trusted-types-reporting-for-HTMLIFrameElement-srcdoc.html (실시간 테스트) (소스)
- trusted-types-reporting-for-HTMLScriptElement-children-change.html (실시간 테스트) (소스)
- trusted-types-reporting-for-HTMLScriptElement-innerHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-HTMLScriptElement.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Range-createContextualFragment.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SVGScriptElement-children-change.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SVGScriptElement-innerHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ServiceWorker-ServiceWorkerContainer-register.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ServiceWorker-eval.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ServiceWorker-function-constructor.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ServiceWorker-importScripts.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ServiceWorker-setTimeout-setInterval.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ShadowRoot-innerHTML.html (실시간 테스트) (소스)
- trusted-types-reporting-for-ShadowRoot-setHTMLUnsafe.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-DedicatedWorker-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-ServiceWorkerContainer-register.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-eval.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-function-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-importScripts.html (실시간 테스트) (소스)
- trusted-types-reporting-for-SharedWorker-setTimeout-setInterval.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-DedicatedWorker-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-ServiceWorkerContainer-register.https.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-SharedWorker-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-eval.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-function-constructor.html (실시간 테스트) (소스)
- trusted-types-reporting-for-Window-setTimeout-setInterval.html (실시간 테스트) (소스)
- trusted-types-reporting.html (실시간 테스트) (소스)
- trusted-types-sandbox-allow-scripts.html (실시간 테스트) (소스)
- trusted-types-sandbox-no-allow-scripts.html (실시간 테스트) (소스)
- trusted-types-source-file-path.html (실시간 테스트) (소스)
- trusted-types-svg-script-set-href.html (실시간 테스트) (소스)
- trusted-types-tojson.html (실시간 테스트) (소스)
- tt-block-eval.html (live test) (소스)
1. 소개
이 섹션은 규범적이지 않습니다.
웹 애플리케이션이 공격자가 제어하는 소스(예: 문서 URL 파라미터 또는 postMessage 채널)에서 값을 받아 적절한 정제 없이 강력한 기능을 가진 다양한 웹 API 함수인 인젝션 싱크에 전달할 때 특정 취약점 유형이 발생합니다.
이러한 이슈는 전통적으로 예방하기 어렵습니다.
애플리케이션은 작성자가 인식하지 못한 채로, 공격자가 제어하는 값을 인젝션 싱크에 흔히 전달합니다. 이는 인젝션 싱크를 호출할 때 입력이 공격자 제어인지 알기가 어렵기 때문입니다.
자바스크립트의 동적 특성상 이러한 패턴이 코드에 포함되지 않았는지 확인하기도 어렵습니다. 수동 코드 리뷰나 자동 코드 분석 과정에서도 자주 놓치게 됩니다. 예를 들어,
aString에 신뢰할 수 없는 데이터가 포함되어 있다면 foo[bar] = aString은 foo와
bar 값에 따라 취약점을 유발할 수 있는 문장입니다.
이 문서는 공격자 제어 데이터가 § 2.1.1 DOM XSS 인젝션 싱크에 도달해 결국 공격자가 제어하는 스크립트 페이로드가
실행되는 DOM 기반 크로스사이트 스크립팅(DOM XSS) 방지에 초점을 맞추고 있습니다. 웹 애플리케이션에는 60개 이상의 인젝션 싱크(Element.innerHTML,
Location.href setter 등)가 존재해 DOM XSS가 빈번하게 일어납니다.
이 문서는 트러스티드 타입을 정의합니다. 이 API는 애플리케이션이 인젝션 싱크를 문자열 대신 스푸핑 불가능한 타입 값만 허용하도록 잠글 수 있게 해줍니다. 이러한 값은 애플리케이션이 정의한 정책에서만 생성됩니다. 이를 통해 작성자는 위험한 API 보호 규칙을 정의하고, 웹 애플리케이션 코드베이스의 작고 격리된 부분만 보호 및 감시, 리뷰하면 돼 전체 공격 표면을 줄일 수 있습니다.
1.1. 목표
-
신뢰할 수 없는 데이터로 강력한 웹 API를 호출해 발생하는 클라이언트 측 취약점(예: DOM XSS) 가능성을 최소화합니다.
-
보안 결정을 애플리케이션의 일부에만 캡슐화하는 설계를 장려합니다.
-
복잡한 웹 애플리케이션 코드베이스의 보안 검토 범위를 줄입니다.
-
동적/정적 분석 도구 지원 하에 일반 프로그래밍 오류 탐지처럼 유용성을 해치지 않으면서 취약점 탐지·노출이 가능하도록 합니다.
1.2. 비목표
-
서버 측에서 생성된 마크업에 대한 인젝션 결과(특히 스크립트 본문의 반사)를 방지하거나 완화하지 않습니다. 서버 측 XSS 벡터에 대해서는 기존 템플릿 시스템이나 CSP script-src를 권장합니다.
-
데이터 유출 방지 등 리소스 격리를 다루지 않습니다. ([Fetch]로 외부 소스 연결 방지 등)
-
서브리소스 로딩 제어는 지원하지 않습니다. 트러스티드 타입은 현재 문서에 스크립트할 수 있는 리소스 로딩만 통제할 목적으로 만듭니다.
-
크로스 오리진 자바스크립트 실행을 방지하지 않습니다(예:
data:URL 등으로 새로운 문서에 JS 코드를 로드하는 것은 제한하지 않습니다). -
웹 애플리케이션 JS 코드의 악의적 작성자가 우회하지 못하게 보호하려고 하지 않습니다. 이를 목적으로 설계하면 과도하게 복잡하고 실용적이지 않기 때문입니다.
1.3. 사용 사례
-
한 작성자가 보안 템플릿 시스템을 사용하는 프레임워크로 복잡한 웹 애플리케이션을 관리합니다. 타사 클라이언트 라이브러리들도 분석, 성능 모니터링 등 부가 작업을 위해 함께 사용됩니다. 이들 컴포넌트가 DOM XSS 취약점을 일으키지 않도록, 작성자는 템플릿 라이브러리에서 트러스티드 타입 정책을 정의하고 § 2.1.1 DOM XSS 인젝션 싱크에 강제 적용합니다.
-
어떤 사이트가 § 2.1.1 DOM XSS 인젝션 싱크를 사용합니다. 개발자는 트러스티드 타입을 적용하고 Content-Security-Policy-Report-Only 헤더 필드로 위반 사항을 모니터링합니다. 위반 발생 시 코드를 안전한 방식으로 리팩토링하여 하나씩 해결합니다. 이후 DOM XSS 인젝션 싱크가 더 이상 호출되지 않게 되어, 트러스티드 타입이 더 이상 필요하지 않게 됩니다. 개발자는 리포트 온리 모드를 끄고 trusted-types 및 require-trusted-types-for 디렉티브를 비활성화합니다. 사이트 기능은 리팩토링 과정 동안 한 번도 저해되지 않았습니다.
-
대규모 팀이 복잡한 클라이언트 애플리케이션을 관리합니다. 이들은 애플리케이션의 보안 요구사항을 만족하는 여러 트러스티드 타입 정책을 만듭니다. 정책 구현과 안전한 추상화를 소수의 집중 리뷰된 파일에 통합하고, 해당 파일에 영향을 주는 커밋은 별도 승인을 거치도록 합니다.
트러스티드 값을 생성해야만 인젝션 싱크에 영향을 줄 수 있기 때문에, 정책 코드 변경에 대한 추가 심사를 통해 개발자들이 코드 조합 대신 안전 추상화만 사용하도록 유도합니다.
DOM XSS 위험을 평가할 때, 보안 심사자는 소규모 공격 표면만 확인합니다. 이들은 CSP 헤더 설정 및 안전 추상화를 제공하는 코드만 집중 검사하고, 나머지 클라이언트 코드 전체는 무시합니다.
-
기존 웹 애플리케이션이 대부분 XSS-safe 패턴을 이용해 DOM과 상호작용합니다(§ 2.1.1 DOM XSS 인젝션 싱크를 사용하지 않음). 단, 일부에서는 JSONP로 추가 스크립트 로드,
innerHTML이나eval등의 위험한 패턴을 사용할 수 있습니다.리뷰 결과, 해당 부분이 실제 XSS를 유발하지 않지만(예: 사용자가 입력한 데이터가 포함되지 않음) 이러한 패턴을 완전히 제거하기는 어렵습니다.
따라서 CSP를 강제 적용할 수 없으며(
'unsafe-eval' 'unsafe-inline'과 같은 안전하지 않은 버전을 쓰지 않는 한), DOM XSS 결함이 있는 코드가 리뷰에서 제외됐거나 미래에 추가될 수도 있습니다.이 위험에 대응하기 위해 작성자는 검토한 부분을 트러스티드 타입으로 변환하고, 트러스티드 타입 강제 적용을 활성화합니다. 앞으로 인젝션 싱크를 사용하는 다른 코드가 있어도 정확히 차단 및 보고할 수 있습니다.
-
보안팀이 클라이언트 코드 내 XSS 취약점이 없는지 점검합니다. 서버 코드는 거의 API 백엔드이기 때문에 구조가 단순하며, 트러스티드 타입이 강제 적용되어 있으므로, 심사자는 오직 트러스티드 타입 정책과 그 규칙만 확인합니다. 이후, 심사된 정책명만 'trusted-types' CSP 디렉티브에서 개발자가 사용할 수 있도록 허용합니다.
그 외 코드(변동이 잦은 라이브러리 등)는 해당 코드가 트러스티드 타입 정책을 생성하지 않는 한 확인 대상에서 제외할 수 있습니다. 그렇지 않으면 코드가 DOM XSS 유발이 불가능합니다.
2. 프레임워크
2.1. 인젝션 싱크
이 섹션은 규범적이지 않습니다.
인젝션 싱크는 오직 신뢰할 수 있거나 검증 또는 적절히 정제된 입력값으로만 호출해야 하는 강력한 웹 API 함수입니다. 공격자가 제어하는(즉, 인젝션된) 입력값으로 호출하면 원치 않는 결과를 초래하며, 이는 보안 취약점으로 간주됩니다.
참고: 본 문서에서 다루는 인젝션 싱크 목록은 § 4 통합에서 정의되어 있습니다.
애플리케이션이 이러한 취약점을 가지고 있는지(예: DOM XSS 취약점) 확인하는 것은 오직 인젝션 싱크 호출만 분석해서는 어렵습니다. 이들의 입력(대부분 문자열)에는 출처 정보가 없기 때문입니다. 예를 들어,
애플리케이션이 코드를 난독화하기 위해 동적으로 생성한 입력값으로 eval()을 호출하는 것은 정상일 수 있지만, 공격자가 주입한 문자열로
eval()을 호출하면 보안 취약점이 됩니다. 그러나 둘을 구별하기란 쉽지 않습니다.
본 문서는 인젝션 싱크를 그 기능에 따라 그룹으로 나누어 정리합니다. 각 그룹에 대한 강제 적용은 trusted-types-sink-group 값으로 제어합니다.
2.1.1. DOM XSS 인젝션 싱크
이 섹션은 규범적이지 않습니다.
DOM XSS 인젝션 싱크는 입력 문자열 값을 평가해, 해당 값이 신뢰할 수 없는 경우 DOM XSS가 발생할 수 있습니다.
예시는 다음과 같습니다:
-
Element속성 중 코드 로드용 URL을 받는 setter(예:HTMLScriptElement.src) -
Element속성 중 실행할 코드를 받는 setter(예:HTMLScriptElement.text) -
eval등 코드를 직접 실행하는 함수, -
'javascript:' URL로의 네비게이션
HTML 파서는 임의의 요소(스크립트 포함) 및 임의 속성 생성이 가능하므로, DOM XSS 인젝션 싱크에는 HTML 파싱 싱크도 포함됩니다:
-
HTML 문자열을 문서에 파싱·삽입하는 함수(예:
Element.innerHTML,ShadowRoot.innerHTML,Element.outerHTMLsetter, Document.write 등) -
호출자 제어 마크업으로 same-origin
Document객체를 새로 생성하는 함수(예:parseFromString())
DOM XSS 인젝션 싱크 보호는 'script'라는 trusted-types-sink-group에 의해 제어됩니다.
2.2. 트러스티드 타입
작성자가 인젝션 싱크로 전달되는 값을 제어할 수 있도록 § 2.2 트러스티드 타입을 도입합니다. 아래 나열된 트러스티드 타입은 특정 컨텍스트에서 인젝션 싱크에 안전하게 사용할 수 있다고 작성자가 신뢰한 값임을 나타냅니다.
참고: 이 맥락에서 신뢰는 애플리케이션 작성자가 해당 값을 인젝션 싱크에서 안전하게 사용할 수 있다고 확신한다는 의미입니다. 안전하다는 것을 보장하지는 않습니다.
참고: 작성자가 특정 값을 어떤 용도로 생성했는지 명확하게 지정할 수 있어, 사용자 에이전트가 타입 기반 체크를 통해 의도를 보존할 수 있습니다. 예를 들어 HTML 스니펫으로 사용할 값을 스크립트 로드에 쓰면 실패합니다.
참고: 모든 트러스티드 타입은 생성 시 불변의 문자열을 감쌉니다. 이 객체는 위조 불가로, 내부 문자열 값을 교체하는 setter 같은 자바스크립트 인터페이스가 없습니다.
참고: 모든 트러스티드 타입의 문자열 변환기는 내부 문자열 값을 반환합니다. 이 방식 덕분에 DOM 문자열 대신 트러스티드 타입을 점진적으로 도입할 수 있으며, 코드 일부에서만 타입을 생산하고 나머지는 기존 문자열을 계속 사용할 수 있습니다. 즉, 트러스티드 타입은 기존 DOM API와 하위 호환성을 지닙니다.
2.2.1. TrustedHTML
TrustedHTML 인터페이스는 개발자가 인젝션
싱크에 HTML로 출력될 수 있다고 확신하는 문자열을 나타냅니다.
이 객체는 TrustedTypePolicy의
createHTML
메서드를 통해 생성되는 문자열 불변 래퍼입니다.
[Exposed =(Window ,Worker )]interface TrustedHTML {stringifier ;DOMString toJSON (); };
TrustedHTML 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.
toJSON() 메서드 단계와
TrustedHTML 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.
2.2.2. TrustedScript
TrustedScript 인터페이스는 개발자가 실행될 수 있다고 확신하는 컴파일되지 않은 스크립트 본문 문자열을 인젝션 싱크에 전달할 수 있게 합니다.
이 객체는 TrustedTypePolicy의
createScript
메서드를 통해 생성되는, 문자열을 감싸는 불변 래퍼입니다.
[Exposed =(Window ,Worker )]interface TrustedScript {stringifier ;DOMString toJSON (); };
TrustedScript 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.
toJSON() 메서드 단계와
TrustedScript 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.
2.2.3. TrustedScriptURL
TrustedScriptURL 인터페이스는 개발자가 외부 스크립트 리소스의 URL로 파싱될 수 있다고 확신하는 문자열을 인젝션 싱크에 전달할 수 있게 합니다.
이 객체는 TrustedTypePolicy의
createScriptURL
메서드를 통해 생성되는, 문자열을 감싸는 불변 래퍼입니다.
[Exposed =(Window ,Worker )]interface TrustedScriptURL {stringifier ;USVString toJSON (); };
TrustedScriptURL 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.
toJSON() 메서드 단계와
TrustedScriptURL 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.
2.3. 정책
트러스티드 타입은 오직 문자열을 지정 타입 객체로 변환하는 규칙을 정의한, 사용자가 정의한 불변 정책을 통해서만 생성할 수 있습니다. 정책은 트러스티드 타입이 따라야 할 사용자 지정 프로그래밍 규칙을 지정할 수 있습니다.
TrustedHTML
객체는 안전하게 애플리케이션에서 사용 가능하며, 예를 들어 innerHTML
setter에 전달해도 입력값이 공격자 제어라 하더라도 정책 규칙 덕분에 안전하게 사용됩니다.
const sanitizingPolicy= trustedTypes. createPolicy( 'sanitize-html' , { createHTML: ( input) => myTrustedSanitizer( input, { superSafe: 'ok' }), }); myDiv. innerHTML= sanitizingPolicy. createHTML( untrustedValue);
참고: 트러스티드 타입 객체는 작성자가 명시적으로 신뢰하는 값을 감쌉니다. 따라서 트러스티드 타입 객체를 생성하는 순간이 사실상 인젝션 싱크가 되어, 해당 인스턴스 생성 코드는 보안상 중요도가 매우 높습니다. 트러스티드 타입 객체 생성을 엄격히 통제하기 위해 생성자는 직접 노출하지 않고 반드시 정책을 통해 생성해야 합니다.
하나의 Realm 내에서 여러 정책을 생성할 수 있어, 애플리케이션 코드 각 부분에 적합한 규칙을 별도로 정의할 수 있습니다.
const cdnScriptsPolicy= trustedTypes. createPolicy( 'cdn-scripts' , { createScriptURL( url) { const parsed= new URL( url, document. baseURI); if ( parsed. origin== 'https://mycdn.example' ) { return url; } throw new TypeError ( 'invalid URL' ); }, }); myLibrary. init({ policy: cdnScriptsPolicy});
참고: 트러스티드 타입 객체는 오직 정책을 통해서만 생성할 수 있습니다. 강제 적용이 활성화되면 오직 정책 코드만 인젝션 싱크 동작을 트리거할 수 있으므로 정책
create* 함수 호출 부분만이 보안상 예민한 코드가 됩니다.
프로그램 전체에서 이처럼 (보통 극히 일부) 코드만 보안 리뷰하면 되고, 인젝션 싱크 그 자체나 나머지 코드는 모니터링 또는 리뷰할 필요가 없습니다. 사용자 에이전트는 이러한 싱크가 매칭되는
트러스티드 타입 객체만 허용하며, 이 객체는 반드시 정책을 통해서만 생성됩니다.
createPolicy
함수는 정책 객체를 반환하고, 정책의 create* 함수가 정책 규칙을 적용한 뒤 트러스티드 타입 객체를 생성합니다.
참고: 입력값을 정제하는 정책은 애플리케이션 어디서든 자유롭게 사용할 수 있지만, 내부에서만(그리고
작성자가 제어하는 값만) 사용하도록 상당히 느슨한 정책을 두어야 하는 경우도 있을 수 있습니다. 예를 들어, 클라이언트 사이드 HTML 템플릿 라이브러리·HTML sanitizer·비동기
플러그인 로더 등은 HTML/URL을 완전 제어가 필요합니다. API 설계는 이를 지원합니다. 각 정책은 참조(즉, createPolicy()의
반환 값)를 얻은 곳에서만 사용됩니다.
따라서 정책 참조를
객체 권한(capability)처럼 취급할 수 있고, 이는 클로저·내부
함수 변수·모듈을 사용해 통제할 수 있습니다.
( function renderFootnote() { const unsafePolicy= trustedTypes. createPolicy( 'html' , { createHTML: input=> input, }); const footnote= await fetch( '/footnote.html' ). then( r=> r. text()); footNote. innerHTML= unsafePolicy. createHTML( footnote); })();
2.3.1.
TrustedTypePolicyFactory
TrustedTypePolicyFactory는
정책
을 생성하고 Trusted Type 객체 인스턴스가
해당 정책 중 하나를 통해 생성되었는지 검증합니다.
참고: 이 팩토리 객체는 전역 객체의 trustedTypes 프로퍼티를 통해
JavaScript에서 노출됩니다. - § 4.1.1
WindowOrWorkerGlobalScope 인터페이스 확장 참고.
[Exposed =(Window ,Worker )]interface TrustedTypePolicyFactory {TrustedTypePolicy createPolicy (DOMString ,policyName optional TrustedTypePolicyOptions = {});policyOptions boolean isHTML (any );value boolean isScript (any );value boolean isScriptURL (any );value readonly attribute TrustedHTML emptyHTML ;readonly attribute TrustedScript emptyScript ;DOMString ?getAttributeType (DOMString ,tagName DOMString ,attribute optional DOMString ?= "",elementNs optional DOMString ?= "");attrNs DOMString ?getPropertyType (DOMString ,tagName DOMString ,property optional DOMString ?= "");elementNs readonly attribute TrustedTypePolicy ?defaultPolicy ; };
TrustedTypePolicyFactory
객체는 연관된 TrustedTypePolicy
기본 정책을 가집니다.
초기 값은 null입니다.
TrustedTypePolicyFactory
객체는 연관된 순서 있는 문자열 집합 생성된 정책 이름들을 가집니다.
초기 값은 « »입니다.
createPolicy(policyName, policyOptions)-
주어진
TrustedTypePolicyOptionspolicyOptions 객체의 규칙을 구현하는 정책 객체를 생성합니다. 허용 가능한 정책 이름은 콘텐츠 보안 정책에 의해 제한될 수 있습니다. 정책 이름이 trusted-types CSP 디렉티브에 정의된 허용 목록에 없다면, 정책 생성은 TypeError로 실패합니다. 또한 고유 정책명이 강제되는 경우('allow-duplicates'를 사용하지 않을 때),createPolicy가 동일policyName으로 두 번 이상 호출되면 정책 생성은 TypeError로 실패합니다.// HTTP Response header: Content-Security-Policy: trusted-types foo trustedTypes. createPolicy( "foo" , {}); // ok. trustedTypes. createPolicy( "bar" , {}); // throws - name not on the allowlist. trustedTypes. createPolicy( "foo" , {}); // throws - duplicate name. 다음 인자를 전달하여 신뢰할 수 있는 타입 정책 생성 알고리즘을 실행한 결과를 반환합니다:
const myPolicy= trustedTypes. createPolicy( 'myPolicy' , { // 이 보안 중요 코드는 보안 리뷰가 필요합니다; // 결함이 있으면 DOM XSS 취약점이 생길 수 있습니다. createHTML( input) { return aSanitizer. sanitize( input) }, createScriptURL( input) { const u= new URL( dirty, document. baseURI); if ( APPLICATION_CONFIG. scriptOrigins. includes( u. origin)) { return u. href; } throw new Error ( '이 오리진에서 스크립트를 로드할 수 없음' ); }, }); document. querySelector( "#foo" ). innerHTML= myPolicy. createHTML( aValue); scriptElement. src= myPolicy. createScriptURL( 'https://scripts.myapp.example/script.js' ); isHTML(value)-
value가
TrustedHTML인스턴스이고 연관된 data 값이 설정돼 있으면 true를 반환합니다. 그렇지 않으면 false입니다.참고:
is*함수들은 주어진 객체가 진짜 Trusted Type 객체(즉, 구성된 정책 중 하나로 생성되었는지)를 확인할 때 사용합니다. 이는 Object.create나 프로토타입 체인 변조로 객체를 위조하는 경우를 판별하기 위함입니다. isScript(value)-
value가
TrustedScript인스턴스이고 연관된 data 값이 설정돼 있으면 true를 반환합니다. 그렇지 않으면 false입니다. isScriptURL(value)-
value가
TrustedScriptURL인스턴스이고 연관된 data 값이 설정돼 있으면 true를 반환합니다. 그렇지 않으면 false입니다. getPropertyType(tagName, property, elementNs)-
작성자가 특정
Element속성(IDL 속성)에 Trusted Type이 필요한지 확인할 수 있습니다.이 함수는 다음 알고리즘 결과를 반환합니다:
-
localName에 tagName의 ASCII 소문자 값을 할당합니다.
-
elementNs가 null 또는 빈 문자열이라면 elementNs를 HTML 네임스페이스로 설정합니다.
-
interface는 localName 및 elementNs에 대한 엘리먼트 인터페이스로 정합니다.
-
expectedType을 null로 설정합니다.
-
아래 표에서 첫 번째 칸이 "*" 또는 interface 이름이고, 두 번째 칸에 property가 있는 행을 찾습니다. 일치하는 행이 있으면 expectedType에 세 번째 칸 값의 인터페이스 이름을 할당합니다.
Element Property name TrustedType HTMLIFrameElement"srcdoc" TrustedHTMLHTMLScriptElement"innerText" TrustedScriptHTMLScriptElement"src" TrustedScriptURLHTMLScriptElement"text" TrustedScriptHTMLScriptElement"textContent" TrustedScript"*" "innerHTML" TrustedHTML"*" "outerHTML" TrustedHTML -
expectedType을 반환합니다.
-
getAttributeType(tagName, attribute, elementNs, attrNs)-
작성자가 특정
Element콘텐츠 속성에 (필요하다면 어떤) Trusted Type이 필요한지 확인할 수 있습니다. 나중에Element.setAttribute호출 시 알맞은 인자 타입이 전달되게 합니다.이 함수는 다음 알고리즘 결과를 반환합니다:
-
localName에 tagName의 ASCII 소문자 값을 할당합니다.
-
attribute에 attribute의 ASCII 소문자 값을 할당합니다.
-
elementNs가 null 또는 빈 문자열이면, elementNs를 HTML 네임스페이스로 설정합니다.
-
attrNs가 빈 문자열이면 attrNs를 null로 설정합니다.
-
interface를 localName과 elementNs에 대한 엘리먼트 인터페이스로 지정합니다.
-
expectedType을 null로 설정합니다.
-
attributeData는 속성을 위한 트러스티드 타입 데이터 가져오기 알고리즘 결과를 다음 인자로 호출해 구합니다:
-
element로 interface
-
attribute
-
attrNs
-
-
attributeData가 null이 아니면 expectedType을 attributeData 네 번째 멤버의 인터페이스 이름 값으로 설정합니다.
-
expectedType을 반환합니다.
-
emptyHTML, of type TrustedHTML, readonly-
TrustedHTML객체이며, data 값이 빈 문자열로 설정되어 있습니다.
emptyScript, of type TrustedScript, readonly-
TrustedScript객체이며, data 값이 빈 문자열로 설정되어 있습니다.
참고: 이 객체는 런타임 환경이 동적 코드 컴파일을 지원하는지 탐지하는 데 사용할 수
있습니다.
네이티브 Trusted Types 구현에서는 eval(TrustedScript)가 동작하지만,
폴리필에서는 eval(TrustedScript)가 입력 값만 반환하고 코드 실행은 안 되므로 제대로 에뮬레이션할 수 없습니다.
// 네이티브 Trusted Types 지원 시 eval(trustedTypes.emptyScript)는 실행되어 falsy undefined 반환. // 지원하지 않을 경우, eval(trustedTypes.emptyScript)는 truthy 객체 반환. const supportsTS= ! eval( trustedTypes. emptyScript); eval( supportsTS? myTrustedScriptObj: myTrustedScriptObj. toString());
defaultPolicy, of type TrustedTypePolicy, readonly, nullable-
기본 정책 값을 반환합니다.
2.3.2. TrustedTypePolicy
정책 객체는 TrustedTypePolicy 인터페이스를 구현하며, Trusted Type 객체를 생성하는 함수 그룹을 정의합니다.
각 create* 함수는 문자열 값을 주어진 Trusted Type 유형으로 변환하거나, 주어진 값의 변환이 허용되지 않는 경우 TypeError를 발생시킵니다.
[Exposed =(Window ,Worker )]interface TrustedTypePolicy {readonly attribute DOMString ;name TrustedHTML createHTML (DOMString ,input any ...);arguments TrustedScript createScript (DOMString ,input any ...);arguments TrustedScriptURL createScriptURL (DOMString ,input any ...); };arguments
각 정책은 이름을 가집니다.
각 TrustedTypePolicy 객체는 TrustedTypePolicyOptions
options 객체와 연관되어 있으며, 정책의 실제 동작을 설명합니다.
createHTML(input, ...arguments)-
Create a Trusted Type 알고리즘을 아래 인수로 실행한 결과를 반환합니다:
- policy
- this 값
- trustedTypeName
"TrustedHTML"- value
- input
- arguments
- arguments
createScript(input, ...arguments)-
Create a Trusted Type 알고리즘을 아래 인수로 실행한 결과를 반환합니다:
- policy
- this 값
- trustedTypeName
"TrustedScript"- value
- input
- arguments
- arguments
createScriptURL(input, ...arguments)-
Create a Trusted Type 알고리즘을 아래 인수로 실행한 결과를 반환합니다:
- policy
- this 값
- trustedTypeName
"TrustedScriptURL"- value
- input
- arguments
- arguments
2.3.3.
TrustedTypePolicyOptions
이 사전은 문자열 값을 신뢰된 값으로 변환하기 위한 작성자 정의 함수들을 보유합니다. 이러한 함수들은 Trusted Type
객체 인스턴스를 직접 생성하지 않습니다. 이 동작은
TrustedTypePolicy에
의해 제공됩니다.
dictionary TrustedTypePolicyOptions {CreateHTMLCallback ;createHTML CreateScriptCallback ;createScript CreateScriptURLCallback ; };createScriptURL callback =CreateHTMLCallback DOMString ? (DOMString ,input any ...);arguments callback =CreateScriptCallback DOMString ? (DOMString ,input any ...);arguments callback =CreateScriptURLCallback USVString ? (DOMString ,input any ...);arguments
2.3.4. 기본 정책
이 섹션은 규범적이지 않습니다.
정책 중 하나인 이름이
"default"인 정책은 특별합니다;
injection sink에 문자열(Trusted
Type 객체 대신)이 전달되면,
이 정책은 사용자 에이전트에 의해 신뢰되지 않은 문자열 값, sink의 Trusted Type, 그리고 sink 타입과 함께 암묵적으로 호출됩니다.
이를 통해 애플리케이션은 위반을 일으키는 대신 대체 동작을 정의할 수 있습니다. 목적은 애플리케이션이 예기치 않은 데이터 흐름에서 복구하고 잠재적으로 공격자가 제어하는 문자열을 "마지막 수단"으로 정제하거나, 안전한 값을 생성할 수 없다면 값을 거부하도록 하는 것입니다. 정책 내에서 발생한 오류는 애플리케이션에 전파됩니다.
기본 정책이 존재하지 않거나, 관련 create* 함수가 null 또는 undefined를 반환하면 CSP 위반이 발생합니다.
엔포스 모드에서는 오류가 발생하지만, 리포트-온리 모드에서는 기본 정책에 전달된 원래의 값이 사용됩니다.
Note: 이 선택적 동작은 여전히 injection sink를 사용하는 레거시 코드를 가진 애플리케이션에 Trusted Type enforcement 를 도입할 수 있게 합니다. 말할 것도 없이, 이 정책은 애플리케이션의 알 수 없는 부분에서 보안 제한을 우회하지 않도록 매우 엄격한 규칙으로 정의되어야 합니다. 극단적인 경우, 느슨하고 동작하지 않는 기본 정책은 injection sink에 대한 접근을 보호하기 위해 Trusted Types를 사용하는 모든 이점을 무력화할 수 있습니다. 가능하다면, 작성자는 기본 정책을 일시적인 기간에만 사용하고, 이 정책을 이용해 injection sink를 비안전하게 사용하는 종속성을 감지·수정하며, 최종적으로 기본 정책 사용을 완전히 중단해야 합니다.
Note: 기본 정책이 어떻게 적용되는지 자세한 내용은 § 3.4 Get Trusted Type compliant string을 참조하십시오.
// Content-Security-Policy: trusted-types default; require-trusted-types-for 'script' trustedTypes. createPolicy( 'default' , { createScriptURL: ( value, type, sink) => { console. log( "Please refactor." ); return value+ '?default-policy-used&type=' + encodeURIComponent( type) + '&sink=' + encodeURIComponent( sink); } }); aScriptElement. src= "https://cdn.example/script.js" ; // Please refactor. console. log( aScriptElement. src); // https://cdn.example/script.js?default-policy-used&type=TrustedScriptURL&sink=HTMLScriptElement%20src
2.4. 강제 적용
Note: 강제 적용은 값이 injection sink에 도달하기 전에 적절한 타입을 가지고 있는지 확인하는 과정입니다.
정책을 생성하고 Trusted Types 객체를 만들 수 있도록 하는 JavaScript API는 항상
(trustedTypes을
통해) 제공됩니다.
injection sink는
보안에 민감한 인자를 문자열화하고, Trusted Type
객체도 내부 문자열 값으로 문자열화되므로, 작성자는 문자열 대신 Trusted Types를 사용할 수 있습니다.
injection sink에 대한 접근을 보호하기 위해, Trusted Types를 사용하는 JavaScript 코드 외에 사용자 에이전트는 엔포스를 실행해야 하며, 즉 주어진 그룹의 injection sink가 절대 문자열 값으로 호출되지 않으며, Trusted Type 값만 사용되는지를 보장해야 합니다. 이 섹션은 작성자가 어떻게 이 엔포싱 동작을 제어할 수 있는지 설명합니다.
작성자는 또 정책 생성을 둘러싼 규칙을 지정하여 정책을 제어할 수 있습니다.
2.4.1. 콘텐츠 보안 정책
애플리케이션은 Content Security Policy를 구성하여 Trusted Type 엔포스를 제어할 수 있습니다. 이 문서는 Trusted Types 규칙에 대응하는 새로운 지시어를 정의합니다. require-trusted-types-for 지시어는 타입이 요구되어야 하는 injection sink 그룹을 지정합니다. trusted-types 지시어는 정책 생성 방식을 제어합니다.
Note: CSP 메커니즘을 사용하면 작성자가 Content-Security-Policy-Report-Only HTTP Response 헤더를 사용해 애플리케이션의 Trusted Types 엔포스를 준비할 수 있습니다.
Note: 대부분의 엔포스 규칙은 다른 명세의 알고리즘을 수정함으로써 정의됩니다. § 4 통합을 참고하십시오.
3. 알고리즘
3.1. Trusted Type Policy 생성
trusted type
policy를 생성하기 위해, TrustedTypePolicyFactory
(factory),
문자열 (policyName), TrustedTypePolicyOptions
사전(options), 그리고
글로벌 객체 (global)이 주어졌을 때 다음 단계를 수행합니다:
-
allowedByCSP를 content security policy에 의해 Trusted Type policy 생성이 차단되어야 하는지 알고리즘을 global, policyName 및 factory의 생성된 정책 이름 값과 함께 실행한 결과로 설정합니다.
-
allowedByCSP가
"Blocked"이면, TypeError를 발생시키고 이후 단계를 중단합니다. -
policyName이
default이고 factory의 기본 정책 값이 null이 아니면, TypeError를 발생시키고 이후 단계를 중단합니다. -
policy를
TrustedTypePolicy객체의 새 인스턴스로 설정합니다. -
policy의
name속성 값을 policyName으로 설정합니다. -
policy의 options 값을 «[ "createHTML" -> options["
createHTML", "createScript" -> options["createScript", "createScriptURL" -> options["createScriptURL" ]»로 설정합니다. -
policyName이
default인 경우, factory의 기본 정책 값을 policy로 설정합니다. -
policy를 반환합니다.
3.2. Trusted Type 생성
trusted type을
생성하려면 TrustedTypePolicy
policy, 타입 이름 trustedTypeName,
문자열 value, 리스트 arguments가 주어지면 다음 단계를 실행합니다:
-
policyValue를 get trusted type policy value를 동일한 인수와 추가적으로 true(throwIfMissing)로 실행한 결과로 설정합니다.
-
알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.
-
policyValue를 문자열화한 결과를 dataString으로 설정합니다.
-
policyValue가 null 또는 undefined이면, dataString을 빈 문자열로 설정합니다.
-
타입 이름이 trustedTypeName인 인터페이스의 새 인스턴스를 반환하며, 연결된 데이터 값은 dataString으로 설정합니다.
3.3. Trusted Type 정책 값 가져오기
trusted type
policy value를 가져오려면 TrustedTypePolicy
policy, 타입 이름 trustedTypeName,
문자열 value, 리스트 arguments, boolean throwIfMissing이 주어지면 아래 단계를 실행합니다:
-
functionName을 주어진 trustedTypeName에 대해 다음 표를 기반으로 함수 이름으로 설정합니다:
함수 이름 Trusted Type 이름 "createHTML" "TrustedHTML" "createScript" "TrustedScript" "createScriptURL" "TrustedScriptURL" -
function을 policy의 options[functionName]으로 설정합니다.
-
function이
null이면,-
throwIfMissing이 true면 TypeError를 발생시킵니다.
-
그렇지 않으면
null을 반환합니다.
-
-
args를 « value »로 설정합니다.
-
Append arguments의 각 항목을 args에 추가합니다.
-
policyValue를 콜백 함수 호출로 function에 args와
"rethrow"을 넘겨 실행한 결과로 설정합니다. -
policyValue를 반환합니다.
3.4. 신뢰된 타입 준수 문자열 가져오기
이 알고리즘은 injection sink에서 사용할 수 있는 문자열을 반환하며, 필요에 따라 일치하는 Trusted Type에서 언래핑할 수 있습니다. 이것은 Trusted Type enforcement 규칙이 준수되었는지 확인합니다.
신뢰된 타입 준수
문자열을 가져오려면 TrustedType
타입(expectedType), 글로벌 오브젝트(global),
TrustedType
또는 문자열(input), 문자열(sink), 문자열(sinkGroup)이 주어졌을 때, 다음 단계를 실행합니다:
-
input이 expectedType의 인스턴스라면, input을 문자열로 변환하여 반환하고 이 단계를 중단합니다.
-
requireTrustedTypes를 sink 타입이 Trusted Type을 요구하는가? 알고리즘을 global, sinkGroup, true와 함께 실행한 결과로 설정합니다.
-
requireTrustedTypes가
false라면, input을 문자열로 변환해 반환하고 이 단계를 중단합니다. -
convertedInput을 기본 정책으로 값 처리를 본 알고리즘과 동일한 인수로 실행한 결과로 설정합니다.
-
알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.
-
convertedInput이
null또는undefined라면, 다음을 실행합니다:-
disposition을 sink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는지 알고리즘을 global, 문자열화된 input을 source로, sinkGroup과 sink를 넘겨 실행한 결과로 설정합니다.
-
disposition이
“Allowed”라면, input을 문자열로 변환해 반환하고 이후 단계를 중단합니다.Note: 이 단계는 기본 정책이 거부되면 보고 모드에서는 무시하고 보고만 하게 합니다.
-
TypeError를 발생시키고 이후 단계를 중단합니다.
-
-
Assert: convertedInput는 expectedType의 인스턴스입니다.
-
convertedInput을 문자열로 변환해 반환합니다.
3.5. 기본 정책으로 값 처리
이 알고리즘은 값을 injection sink에 할당할 때 기본 정책이 존재한다면 해당 정책을 거칩니다.
기본 정책으로 값
처리를 하려면 TrustedType
타입(expectedType), 글로벌 오브젝트(global),
TrustedType
또는 문자열(input), 문자열(sink)이 주어졌을 때, 다음 단계를 실행합니다:
-
defaultPolicy를 global의 trusted type policy factory의 기본 정책 값으로 설정합니다.
-
policyValue를 get trusted type policy value를 다음 인수로 실행한 결과로 설정합니다:
-
defaultPolicy를 policy로
-
문자열화된 input을 value로
-
expectedType의 타입 이름을 trustedTypeName으로
-
« trustedTypeName, sink »를 arguments로
-
false를 throwIfMissing으로
-
-
알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.
-
policyValue가 null 또는 undefined라면, policyValue를 반환합니다.
-
dataString을 policyValue를 문자열화한 결과로 설정합니다.
-
타입 이름이 trustedTypeName인 인터페이스의 새 인스턴스를 dataString을 값으로 반환합니다.
3.6. 스크립트 텍스트 준비
스크립트 텍스트를 준비하려면
HTMLScriptElement
또는 SVGScriptElement
(script)이 주어졌을 때, 아래 단계를 수행합니다:
-
sink를 script가
HTMLScriptElement이면 "HTMLScriptElement text"로, 아니면 "SVGScriptElement text"로 설정합니다. -
script의 script text 값이 child text content와 다르면, script의 script text를 아래와 같이 신뢰된 타입 준수 문자열 가져오기 알고리즘의 실행값으로 설정합니다:
-
TrustedScriptURL을 expectedType으로, -
script의
Document의 relevant global object를 global로, -
script의 child text content 속성 값을 input으로,
-
sink,
-
'script'를 sinkGroup으로.
알고리즘에서 오류가 발생하면, 오류를 다시 발생시킵니다.
-
3.7. 신뢰된 타입 준수 속성 값 가져오기
신뢰된
타입 준수 속성 값을 가져오려면 문자열 attributeName, 문자열 attributeNs, Element
element와 TrustedType
또는 문자열 newValue가 주어졌을 때, 다음 단계를 수행합니다:
-
attributeNs가 빈 문자열이면 attributeNs를 null로 설정합니다.
-
attributeData를 속성의 신뢰된 타입 데이터 가져오기 알고리즘을 다음 인수로 실행한 결과로 합니다:
-
element
-
attributeName
-
attributeNs
-
-
attributeData가 null이면:
-
newValue가 문자열이면 newValue를 반환합니다.
-
Assert: newValue는
TrustedHTML,TrustedScript또는TrustedScriptURL입니다. -
value의 연결된 데이터를 반환합니다.
-
-
expectedType을 attributeData의 네 번째 멤버 값으로 설정합니다.
-
sink를 attributeData의 다섯 번째 멤버 값으로 설정합니다.
-
아래 인수로 신뢰된 타입 준수 문자열 가져오기 알고리즘을 실행한 결과를 반환합니다:
-
expectedType
-
newValue를 input으로
-
element의 node document의 relevant global object를 global로
-
sink
-
'script'를 sinkGroup으로
-
알고리즘에서 오류가 발생하면, 오류를 다시 발생시킵니다.
3.8. 속성의 신뢰된 타입 데이터 가져오기
속성의 신뢰된 타입 데이터 가져오기는 element, attribute, attributeNs가 주어졌을 때, 아래 단계를 수행합니다:
아래에서 사용하는 이벤트 핸들러 콘텐츠 속성 개념은 모호합니다. 이 명세는 이벤트 핸들러 속성을 식별하기 위한 더 나은 메커니즘이 필요합니다. https://github.com/w3c/trusted-types/issues/520 참조.
-
data를 null로 설정합니다.
-
만약 attributeNs가 null이라면, « HTML 네임스페이스, SVG 네임스페이스, MathML 네임스페이스 » 포함한다 element의 네임스페이스, 그리고 attribute가 이벤트 핸들러 콘텐츠 속성의 이름인 경우:
-
(
Element, null, attribute,TrustedScript, "Element " + attribute)를 반환합니다.
-
-
아래 표에서 element가 첫 번째 열, attributeNs가 두 번째 열, attribute가 세 번째 열과 일치하는 행을 찾습니다. 일치하는 행이 있으면 data를 그 행으로 설정합니다.
Element Attribute namespace Attribute local name TrustedType Sink HTMLIFrameElementnull "srcdoc" TrustedHTML"HTMLIFrameElement srcdoc" HTMLScriptElementnull "src" TrustedScriptURL"HTMLScriptElement src" SVGScriptElementnull "href" TrustedScriptURL"SVGScriptElement href" SVGScriptElementXLink 네임스페이스 "href" TrustedScriptURL"SVGScriptElement href" -
data를 반환합니다.
4. 통합
typedef (TrustedHTML or TrustedScript or TrustedScriptURL );TrustedType
4.1. HTML과의 통합
Window
및 Worker
개체에는 trusted type policy factory가 있으며,
이는 TrustedTypePolicyFactory
객체입니다.
4.1.1. WindowOrWorkerGlobalScope 인터페이스 확장
이 문서는 WindowOrWorkerGlobalScope
인터페이스를 HTML에서 정의된 대로 확장합니다:
partial interface mixin WindowOrWorkerGlobalScope {readonly attribute TrustedTypePolicyFactory ; };trustedTypes
trustedTypes
getter의 단계는 this의
relevant global object의 trusted
type policy factory를 반환하는 것입니다.
4.1.2. 스크립트에서의 enforcement
이 문서는 HTMLScriptElement
child text content의 설정 방식을 수정하여 애플리케이션이 동적으로 생성된 스크립트를 제어할
수 있게 합니다. 이 작업은
innerText
와 textContent
속성을 HTMLScriptElement
에 직접 추가하여 구현합니다.
해당 속성들은 본래 속성과 똑같이 동작하지만, 추가적으로 신뢰된 타입 준수 문자열 가져오기를 호출합니다.
Note: 이러한 IDL 속성을 사용하는 것이 스크립트의 URL이나 텍스트를 동적으로 설정하는 권장 방식입니다. 속성 노드나 텍스트 노드를 직접 조작하면, 스크립트가 준비될 때 최종 값에 대해 기본 정책이 호출됩니다.
partial interface HTMLScriptElement { [CEReactions ]attribute (TrustedScript or [LegacyNullToEmptyString ]DOMString ); [innerText CEReactions ]attribute (TrustedScript or DOMString )?; [textContent CEReactions ]attribute (TrustedScriptURL or USVString ); [src CEReactions ]attribute (TrustedScript or DOMString ); };text
4.1.2.1. 신뢰된 값이 있는 슬롯
HTMLScriptElement
및 SVGScriptElement
에는 다음이 있습니다:
- 연관된 문자열 script text.
-
준수 sink를 통해 설정된 실행할 스크립트 본문을 담고 있는 문자열입니다. script의 child text content와 동등합니다. 초기값은 빈 문자열입니다.
4.1.2.2.
innerText
IDL 속성
innerText
setter의 단계는 다음과 같습니다:
-
value를 신뢰된 타입 준수 문자열 가져오기를
TrustedScript, this의 relevant global object, 주어진 값,HTMLScriptElement innerText,script로 호출한 결과로 설정합니다. -
this의 script text 값을 value로 설정합니다.
-
set the inner text steps를 this와 value로 실행합니다.
innerText
getter의 단계:
-
get the text steps를 this로 실행한 결과를 반환합니다.
4.1.2.3.
textContent
IDL 속성
textContent
setter의 단계는, 주어진 값이 null이면 빈 문자열로 간주한 다음 아래에 설명된 대로 수행합니다.
-
value를 신뢰된 타입 준수 문자열 가져오기를
TrustedScript, this의 relevant global object, 주어진 값,HTMLScriptElement textContent,script로 호출한 결과로 설정합니다. -
this의 script text 값을 value로 설정합니다.
-
set text content를 this와 value로 실행합니다.
textContent
getter의 단계:
-
get text content를 this로 실행한 결과를 반환합니다.
Note: 현재 SVGScriptElement에
해당하는 기능은 추가되지 않았습니다.
https://github.com/w3c/trusted-types/issues/512를
참조하세요.
4.1.2.4.
text
IDL 속성
text
setter 단계 알고리즘을 아래와 같이 갱신합니다.
-
value를 신뢰된 타입 준수 문자열 가져오기를
TrustedScript, this의 relevant global object, 주어진 값,HTMLScriptElement text,script로 호출한 결과로 설정합니다. - this의 script text 값을 주어진 값으로 설정합니다.
-
String replace all을 주어진 값으로 this 안에서 실행합니다.
4.1.2.5.
src
IDL 속성
src
getter의 단계:
- element를 this의 get the element 실행 결과로 설정합니다.
- contentAttributeValue를 this의 get the content attribute 실행 결과로 설정합니다.
- contentAttributeValue가 null이면 빈 문자열을 반환합니다.
- urlString을 element의 node document를 기준으로 contentAttributeValue를 URL 인코딩-파싱-직렬화 한 결과로 설정합니다.
- urlString이 failure가 아니면 urlString을 반환합니다.
- contentAttributeValue를 스칼라 값 문자열로 변환하여 반환합니다.
src
setter의 단계:
-
value를 신뢰된 타입 준수 문자열 가져오기를
TrustedScriptURL, this의 relevant global object, 주어진 값,HTMLScriptElement src,script로 호출한 결과로 설정합니다. - this의 src content attribute를 value로 설정합니다.
4.1.2.6. 파서에서 슬롯 값 설정
이 문서는 HTML 파서가 script가 생성될 때 script text 값을 설정하도록 수정합니다.
The text insertion mode 알고리즘을 다음과 같이 수정합니다:
- end tag의 tag name이 "script"인 경우
-
...
script의 script text 값을 그 child text content로 설정합니다.
active speculative HTML parser가 null이면 prepare the script element script를 실행합니다. 이로 인해 일부 스크립트가 실행될 수 있고, 토크나이저에 새 문자가 삽입될 수 있으며, 토크나이저가 더 많은 토큰을 출력하여 reentrant parser 호출을 유발할 수 있습니다.
...
위 알고리즘은 script element의 내용이 파싱 도중 변경되는 경우를 고려하지 않습니다. 구현자는 이 케이스를 대비해야 합니다. https://github.com/w3c/trusted-types/issues/507 참조.
SVG script elements 처리에 대한
정식 정의가 없습니다.
하지만 구현에서는 SVGScriptElement
처리도 유사하게 변경해야 합니다.
4.1.2.7. 슬롯 값 검증
prepare the script element 알고리즘의 처음 몇 단계를 아래와 같이 수정합니다:
-
el의 already started가 true면 return합니다.
-
parser document를 el의 parser document로 설정합니다.
-
el의 parser document를 null로 설정합니다.
이렇게 하면 파서가 삽입한
script요소가 파서가 이를 실행하려 할 때(예: 비었거나 지원되지 않는 스크립팅 언어일 때) 실행에 실패하면, 다른 스크립트가 나중에 이를 변경하여 다시 실행할 수 있습니다. -
parser document가 null이 아니고, el이
async속성을 가지고 있지 않으면 el의 force async를 true로 설정합니다.이렇게 하면 파서가 삽입한
script요소가 실행에 실패해도, 나중에 동적으로 업데이트되어 실행될 경우async속성이 없어도 비동기로 실행됩니다. -
el에 대해 스크립트 텍스트 준비 알고리즘을 실행합니다. 알고리즘에서 오류가 발생했다면 return 합니다.
-
source text를 el의
child text content.script text 값. - ...
SVG script elements 처리에
대한 정식 정의가 없습니다. 하지만 구현에서는 SVGScriptElement
처리도 유사하게 변경해야 합니다.
4.2. DOM과의 통합
Note: https://github.com/whatwg/dom/pull/1268를 참고하세요. 여기에서 이 통합이 머지되었습니다.
4.3. Content Security Policy와의 통합
4.3.1. require-trusted-types-for 지시어
이 문서는 require-trusted-types-for라는 새로운 Content Security Policy 지시어를 정의합니다.
require-trusted-types-for 지시어는 현재 realm 내 특정 그룹의 모든 injection sink에 대해 Trusted Types 프레임워크를 구성합니다. 특히 주어진 그룹의 injection sink에 문자열 값이 전달될 때(즉, 해당 sink에 타입 기반 enforcement가 활성화되어야 할지 여부) 어떤 동작을 가져야 하는지 정의합니다.
Note: 현재 § 2.1.1 DOM XSS injection sink에 대한 enforcement만 명세되어 있습니다.
지시어의 name 및 value 구문은 다음 ABNF로 설명됩니다:
directive-name = "require-trusted-types-for" directive-value = trusted-types-sink-group-keyword *( required-ascii-whitespace trusted-types-sink-group-keyword) trusted-types-sink-group-keyword = "'" trusted-types-sink-group "'" trusted-types-sink-group = "script"
Content-Security-Policy: require-trusted-types-for 'script'
4.3.1.1. require-trusted-types-for
Pre-Navigation check
request (request), 문자열 navigation type, policy (policy)가 주어지면, 아래 알고리즘은 탐색이 require-trusted-types-for 지시어를 위반하면
"Blocked"를, 그렇지 않으면 "Allowed"를 반환합니다. 이 알고리즘은 require-trusted-types-for 지시어의 pre-navigation check를 구성합니다:
Note: 이 알고리즘은 javascript: URL에 대한 네비게이션으로
실행될 코드도,
다른 CSP 지시어로 부과된 제한과 별도로, 기본 정책의 createScript 함수를 반드시 거치도록 보장합니다.
-
request의 url의 scheme이
"javascript"가 아니면"Allowed"를 반환하고 더 이하 단계를 중단합니다. -
urlString을 URL serializer를 request의 url에 실행한 결과로 설정합니다.
-
encodedScriptSource를 urlString에서 선행
"javascript:"를 제거한 값으로 설정합니다. -
convertedScriptSource를 기본 정책으로 값 처리 알고리즘에 다음 인수를 넘겨 실행한 결과로 설정합니다:
-
TrustedScript를 expectedType으로 -
request의 clients의 global object를 global로
-
encodedScriptSource를 input으로
-
"Location href"를 sink로
알고리즘에서 오류가 발생하거나 convertedScriptSource가
TrustedScript객체가 아니면 "Blocked"를 반환하고, 추가 단계를 중단합니다. -
-
urlString을 stringified convertedScriptSource 앞에
"javascript:"를 붙여서 만듭니다. -
newURL을 URL parser를 urlString에 실행한 결과로 설정합니다. 파서가 failure를 반환하면
"Blocked"를 반환하고 추가 단계를 중단합니다. -
request의 url을 newURL로 설정합니다.
Note: pre-navigation check에서
javascript:URL에는 다른 CSP 지시어가 적용되지 않습니다. javascript: URL을 확인하는 다른 지시어는, 나중에 inline check 단계에서 수정된 URL에 대해 동작합니다. -
"Allowed"를 반환합니다.
4.3.2. trusted-types 지시어
이 문서는 trusted-types라는 새로운 Content Security Policy 지시어를 정의합니다. trusted-types 지시어는 Trusted Type 정책 생성 제어에 사용됩니다.
지시어의 name 및 value 구문은 아래 ABNF로 설명됩니다:
directive-name = "trusted-types" directive-value = serialized-tt-configuration serialized-tt-configuration = ( tt-expression *( required-ascii-whitespace tt-expression ) ) tt-expression = tt-policy-name / tt-keyword / tt-wildcard tt-wildcard = "*" tt-policy-name = 1*( ALPHA / DIGIT / "-" / "#" / "=" / "_" / "/" / "@" / "." / "%") tt-keyword = "'allow-duplicates'" / "'none'"
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types one two
Content-Security-Policy: trusted-types; require-trusted-types-for 'script'
키워드 'none'을 사용하여 위와 같이 명시적으로 표현할 수 있습니다:
키워드 'allow-duplicates'는 이미 사용된 이름을 가진 정책도 생성할 수 있도록 허용합니다.
default라는 이름의 정책이 목록에 있으면, 이는 기본
정책을 의미합니다.
모든 문자열이 injection sink에 전달될
때 바로 거부되는 대신, 반드시 해당 정책을 거칩니다.
4.3.3. Sink 타입이 Trusted Types를 요구하는가?
이 알고리즘은 injection sink가 Trusted Type을 필요로 하면
true를, 그렇지 않으면 false를 반환합니다.
Sink 타입이 Trusted Types를 요구하는가? 알고리즘은 global object (global), 문자열 (sinkGroup), 불리언 (includeReportOnlyPolicies)가 주어졌을 때, 다음 단계를 수행합니다:
-
global의 CSP list의 각 policy에 대해:
-
policy의 directive set에 directive가 없거나 그 name이
"require-trusted-types-for"가 아니라면, 다음 policy로 넘어감. -
directive를 policy의 directive set에서 이름이
"require-trusted-types-for"인 directive로 설정함. -
directive의 value에 trusted-types-sink-group 중 sinkGroup과 일치하는 것이 없으면, 다음 policy로 넘어감.
-
enforced를 policy의 disposition이
"enforce"이면 true, 아니면 false로 설정함. -
enforced가 true이면 true를 반환.
-
includeReportOnlyPolicies가 true이면 true를 반환.
-
-
false 반환.
4.3.4. Sink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는가?
이 알고리즘은 injection sink가 Trusted Type을 필요로 하면
"Blocked"를, 그렇지 않으면 "Allowed"를 반환합니다.
Sink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는가? 알고리즘은 global object (global), 문자열 (sink), 문자열 (sinkGroup), 문자열 (source)가 주어지면 다음 단계를 수행합니다:
-
result를
"Allowed"로 설정함. -
sample을 source로 설정함.
-
sink가
"Function"이면,-
sample이
"function anonymous"로 시작하면, sample에서 이를 제거함. -
그렇지 않고 sample이
"async function anonymous"로 시작하면, sample에서 이를 제거함. -
그렇지 않고 sample이
"function* anonymous"로 시작하면, sample에서 이를 제거함. -
그렇지 않고 sample이
"async function* anonymous"로 시작하면, sample에서 이를 제거함.
-
-
global의 CSP list의 각 policy에 대해:
-
policy의 directive set에 directive가 없거나 name이
"require-trusted-types-for"가 아니라면 다음 policy로 넘어감. -
directive를 policy의 directive set에서 이름이
"require-trusted-types-for"인 directive로 설정. -
directive의 value에 trusted-types-sink-group가 sinkGroup과 일치하는 것이 없으면 다음 policy로 넘어감.
-
violation을 Create a violation object for global, policy, and directive로 global, policy,
"require-trusted-types-for"를 넘겨 실행한 결과로 설정. -
violation의 resource를
"trusted-types-sink"로 설정. -
trimmedSample을 sample의 첫 40자 만큼의 부분 문자열로 설정.
-
violation의 sample을
"|"구분자로 « sink, trimmedSample »를 연결한 값으로 설정. -
Report a violation를 violation으로 실행.
-
policy의 disposition이
"enforce"이면 result를"Blocked"로 설정.
-
-
result 반환.
4.3.5. Trusted Type 정책 생성을 Content Security Policy에서 차단해야 하는가?
이 알고리즘은 TrustedTypePolicy
를 생성하면 안 되는 경우 "Blocked"를, 그렇지 않으면 "Allowed"를 반환함.
Trusted Type 정책 생성을 Content Security Policy에서 차단해야 하는가? 알고리즘은 global object (global), 문자열 (policyName), 문자열 리스트 (createdPolicyNames)가 주어졌을 때, 아래 단계를 실행합니다:
-
result를
"Allowed"로 설정함. -
global의 CSP list의 각 policy에 대해:
-
createViolation을 false로 설정.
-
policy의 directive set에 directive가 없거나 name이
"trusted-types"가 아니라면, 다음 policy로 넘어감. -
directive를 policy의 directive set에서 이름이
"trusted-types"인 directive로 설정함. -
directive의 value가 tt-keyword 중
'none'과 일치하는 것만 포함하면 createViolation을 true로 설정.Note: 다른 키워드/정책명이 있으면 'none' 키워드는 무시됩니다.
-
createdPolicyNames에 policyName이 포함되어 있고 directive의 value에 tt-keyword 중
'allow-duplicates'에 해당하는 값이 없으면 createViolation을 true로 설정.Note:
trusted-types policyA policyB 'allow-duplicates'는 동일 이름 정책 중복 생성을 허용합니다. -
directive의 value에 policyName과 값이 같은 tt-policy-name이 없고 tt-wildcard가 없으면 createViolation을 true로 설정.
Note:
trusted-types *는 임의의 고유 이름 정책 생성을 허용합니다. 중복된 이름 허용하려면trusted-types * 'allow-duplicates'또는 아예trusted-types지시어를 생략합니다. -
createViolation이 false면 다음 policy로 넘어감.
-
violation을 Create a violation object for global, policy, and directive로 global, policy,
"trusted-types"를 넘겨 실행한 결과로 설정. -
violation의 resource를
"trusted-types-policy"로 설정함. -
violation의 sample을 policyName의 최대 40자 부분 문자열로 설정함.
-
Report a violation를 violation으로 실행.
-
policy의 disposition이
"enforce"이면 result를"Blocked"로 설정.
-
-
result를 반환.
5. 보안 고려사항
Trusted Types는 적극적으로 악의적인 실행 환경에서 injection sinks에 대한 접근을 보호하기 위한 것이 아닙니다. 애플리케이션은 비악의적 작성자가 작성한다고 가정합니다. 목적은 정책 제한을 적극적으로 우회하려는 1st-party 악의적 코드에 대한 방어가 아니라, 보안 버그로 이어질 수 있는 개발자 실수를 예방하는 것입니다. 아래는 Trusted Types가 강제 적용된 환경에서도 여전히 위험한 것으로 확인된 벡터를 나열합니다.
5.1. 크로스 문서 벡터
Trusted Types가 강제 적용된 창에서 실행되는 코드는 정책 우회 노드를 동적으로 생성할 수 없지만,
이런 노드가 동일 제약을 갖지 않는 다른 창의 문서에서 import/adopt될 수는 있습니다.
즉, 제한 문서와 비제한 문서를 악의적으로 연결하면 Trusted Types를 우회할 수 있습니다.
극단적으로, 제한 문서가 문자열에서 Blob을
만들어 거기로 네비게이션 시킬 수 있습니다.
CSP 전파 규칙(Content Security
Policy 3 § 7.8 CSP Inheriting to avoid bypasses 참조)은 이 문제를 부분적으로 해결합니다.
새로운 local scheme 문서가 동일 제한을 상속받으므로, 예를 들어 script-src 제한을 사용해
Blob
내용 내 삽입 스크립트 실행을 막을 수 있습니다.
전체적으로는, Origin Policy와 같은
별도의 메커니즘을 통해 전체 오리진에 대한 기본 보안 규칙 적용이 필요합니다.
5.2. 폐기된 기능
오래전에 폐기되고 거의 사용되지 않는 일부 플랫폼 기능은 Trusted Types의 적용을 받지 않으며, 악의적 작성자가 제약을 우회하는 데 사용할 수 있습니다:
5.3. 스크립트 gadget
Trusted Types 로직은 문자열로부터 DOM 트리를 생성하는 많은 연산에 적용되지만, 문서 내 모든 DOM 트리 생성을 보호하는 메커니즘으로 간주해서는 안 됩니다. 이는 특히 script gadgets와 관련하여 중요합니다. 애플리케이션이 보통 무해한 DOM 요소/속성 내용을 기반으로 동작하는 경우, DOM API를 직접 사용하는 개발자는 Trusted Types 없이도 gadget을 발생시킬 수 있습니다. 그러나 gadget이 DOM XSS를 발생시키려면 반드시 정책을 통해 Trusted Type 값을 얻어야 합니다. 정책의 규칙이 데이터를 직접 검증/제약하지 않는 한, 정책에 전달하는 데이터가 신뢰할 수 있는지 작성자가 점검해야 합니다.
5.4. 정책 설계 모범 사례
Trusted Types는 injection sinks를 통한 취약성 유입 범위를 policies 구현체로 국한합니다. 이 구조에서, 보안에 취약한 정책도 injection sinks를 신뢰할 수 없는 데이터에 노출시킬 수 있습니다. 반드시 모든 입력에 대해 안전한 정책이거나, 또는 취약한 정책은 공격자가 제어할 수 없는 입력에만 호출되도록 사용을 제한해야 합니다.
정책이 커스텀 JavaScript 코드이기 때문에, 전역 상태에 크게 의존하여 작성될 수 있습니다. 이는 지양해야 하며, 가능한 한 자체적으로 동작해야 합니다. 보안 의사결정에 영향을 주는 모든 객체가 사실상 정책이므로, 이들도 함께 보호·리뷰해야 합니다.
6. 프라이버시 고려사항
이 명세는 애플리케이션 내 실행되는 스크립트의 동작을 부분적으로 관찰·변경할 수 있습니다. 예를 들어, injection sinks에 대해 특정 연산의 실패를 유발하거나, 기본 정책으로 효과를 감시 및 변경할 수 있습니다. 단, 초기 스크립트는 이미 적절한 프로퍼티 디스크립터를 오버라이드하여 이런 기능을 자체적으로 구현 가능합니다.
애플리케이션이 Trusted Types 제한 위반을 보고할 수 있습니다. 위반 리포트에는 injection sink에 전달된 페이로드(최대 40자, sink명 포함)가 일부 포함될 수 있습니다. 이 기능은 Content Security Policy의 리포트 메커니즘을 재사용합니다.
7. 구현 참고사항
7.1. 브라우저/벤더 확장 및 애드온
Trusted Types의 제한은 브라우저 애드온/확장, 북마크릿 등 사용자 에이전트의 동작을 방해해서는 안 됩니다. 이런 종류의 기능들은 [html-design-principles]에서 밝혀진 대로, 작성자보다 사용자의 우선권을 보장해야 합니다. 특히, 확장 기능은 injection sinks에 문자열을 전달할 때 기본 정책 실행, 위반 생성, 값 거부가 일어나지 않아야 합니다.