트러스티드 타입(Trusted Types)

W3C 워킹 드래프트,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2025/WD-trusted-types-20251103/
최신 공개 버전:
https://www.w3.org/TR/trusted-types/
에디터스 드래프트:
https://w3c.github.io/trusted-types/dist/spec/
이전 버전:
히스토리:
https://www.w3.org/standards/history/trusted-types/
피드백:
public-webappsec@w3.org 제목 줄에 “[trusted-types] … 메시지 주제 …” 사용 (아카이브)
GitHub
명세 내 인라인
에디터:
(Google LLC)
이전 에디터:
(Google LLC)
테스트 슈트:
https://wpt.fyi/results/trusted-types/

개요

애플리케이션이 강력한 API를 잠그고, 문자열 대신 스푸핑이 불가능한 타입 값만 허용하도록 하여 공격자가 제어하는 입력값을 사용해 이러한 API를 사용할 때 발생할 수 있는 취약점을 방지하는 API입니다.

이 문서의 상태

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

이 문서는 웹 애플리케이션 보안 워킹 그룹에서 권고안 절차를 통해 워킹 드래프트로 발행하였습니다. 이 문서는 W3C 권고안이 되는 것을 목표로 합니다.

(아카이브됨) 공개 메일링 리스트 public-webappsec@w3.org (자세한 내용은 설명서 참고) 이 명세에 대한 논의에 권장됩니다. 이메일 발송 시, 제목에 “trusted-types”를 반드시 포함해 주시기 바랍니다. 예시: “[trusted-types] …의견 요약…

워킹 드래프트로서의 출판은 W3C 및 회원사의 보증을 의미하지 않습니다. 이 문서는 초안 문서이며 언제든지 수정, 대체, 폐지될 수 있습니다. 이 문서를 진행 중인 작업 외에 다른 용도로 인용하는 것은 부적절합니다.

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

본 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 제작하였습니다. W3C는 이 그룹에 관련한 특허 공개 목록을 관리합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 만약 누군가 필수 클레임이 포함된 특허를 보유하고 있다고 판단되는 경우, W3C 특허 정책 6항에 따라 정보를 공개해야 합니다.

본 문서는 2025년 8월 18일자 W3C 프로세스 문서를 따릅니다.

테스트

1. 소개

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

웹 애플리케이션이 공격자가 제어하는 소스(예: 문서 URL 파라미터 또는 postMessage 채널)에서 값을 받아 적절한 정제 없이 강력한 기능을 가진 다양한 웹 API 함수인 인젝션 싱크에 전달할 때 특정 취약점 유형이 발생합니다.

이러한 이슈는 전통적으로 예방하기 어렵습니다. 애플리케이션은 작성자가 인식하지 못한 채로, 공격자가 제어하는 값을 인젝션 싱크에 흔히 전달합니다. 이는 인젝션 싱크를 호출할 때 입력이 공격자 제어인지 알기가 어렵기 때문입니다. 자바스크립트의 동적 특성상 이러한 패턴이 코드에 포함되지 않았는지 확인하기도 어렵습니다. 수동 코드 리뷰나 자동 코드 분석 과정에서도 자주 놓치게 됩니다. 예를 들어, aString에 신뢰할 수 없는 데이터가 포함되어 있다면 foo[bar] = aStringfoobar 값에 따라 취약점을 유발할 수 있는 문장입니다.

이 문서는 공격자 제어 데이터가 § 2.1.1 DOM XSS 인젝션 싱크에 도달해 결국 공격자가 제어하는 스크립트 페이로드가 실행되는 DOM 기반 크로스사이트 스크립팅(DOM XSS) 방지에 초점을 맞추고 있습니다. 웹 애플리케이션에는 60개 이상의 인젝션 싱크(Element.innerHTML, Location.href setter 등)가 존재해 DOM XSS가 빈번하게 일어납니다.

이 문서는 트러스티드 타입을 정의합니다. 이 API는 애플리케이션이 인젝션 싱크를 문자열 대신 스푸핑 불가능한 타입 값만 허용하도록 잠글 수 있게 해줍니다. 이러한 값은 애플리케이션이 정의한 정책에서만 생성됩니다. 이를 통해 작성자는 위험한 API 보호 규칙을 정의하고, 웹 애플리케이션 코드베이스의 작고 격리된 부분만 보호 및 감시, 리뷰하면 돼 전체 공격 표면을 줄일 수 있습니다.

1.1. 목표

1.2. 비목표

1.3. 사용 사례

2. 프레임워크

2.1. 인젝션 싱크

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

인젝션 싱크는 오직 신뢰할 수 있거나 검증 또는 적절히 정제된 입력값으로만 호출해야 하는 강력한 웹 API 함수입니다. 공격자가 제어하는(즉, 인젝션된) 입력값으로 호출하면 원치 않는 결과를 초래하며, 이는 보안 취약점으로 간주됩니다.

참고: 본 문서에서 다루는 인젝션 싱크 목록은 § 4 통합에서 정의되어 있습니다.

애플리케이션이 이러한 취약점을 가지고 있는지(예: DOM XSS 취약점) 확인하는 것은 오직 인젝션 싱크 호출만 분석해서는 어렵습니다. 이들의 입력(대부분 문자열)에는 출처 정보가 없기 때문입니다. 예를 들어, 애플리케이션이 코드를 난독화하기 위해 동적으로 생성한 입력값으로 eval()을 호출하는 것은 정상일 수 있지만, 공격자가 주입한 문자열로 eval()을 호출하면 보안 취약점이 됩니다. 그러나 둘을 구별하기란 쉽지 않습니다.

본 문서는 인젝션 싱크를 그 기능에 따라 그룹으로 나누어 정리합니다. 각 그룹에 대한 강제 적용trusted-types-sink-group 값으로 제어합니다.

2.1.1. DOM XSS 인젝션 싱크

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

DOM XSS 인젝션 싱크는 입력 문자열 값을 평가해, 해당 값이 신뢰할 수 없는 경우 DOM XSS가 발생할 수 있습니다.

예시는 다음과 같습니다:

HTML 파서는 임의의 요소(스크립트 포함) 및 임의 속성 생성이 가능하므로, DOM XSS 인젝션 싱크에는 HTML 파싱 싱크도 포함됩니다:

DOM XSS 인젝션 싱크 보호는 'script'라는 trusted-types-sink-group에 의해 제어됩니다.

2.2. 트러스티드 타입

작성자가 인젝션 싱크로 전달되는 값을 제어할 수 있도록 § 2.2 트러스티드 타입을 도입합니다. 아래 나열된 트러스티드 타입은 특정 컨텍스트에서 인젝션 싱크에 안전하게 사용할 수 있다고 작성자가 신뢰한 값임을 나타냅니다.

참고: 이 맥락에서 신뢰는 애플리케이션 작성자가 해당 값을 인젝션 싱크에서 안전하게 사용할 수 있다고 확신한다는 의미입니다. 안전하다는 것을 보장하지는 않습니다.

참고: 작성자가 특정 값을 어떤 용도로 생성했는지 명확하게 지정할 수 있어, 사용자 에이전트가 타입 기반 체크를 통해 의도를 보존할 수 있습니다. 예를 들어 HTML 스니펫으로 사용할 값을 스크립트 로드에 쓰면 실패합니다.

참고: 모든 트러스티드 타입은 생성 시 불변의 문자열을 감쌉니다. 이 객체는 위조 불가로, 내부 문자열 값을 교체하는 setter 같은 자바스크립트 인터페이스가 없습니다.

참고: 모든 트러스티드 타입의 문자열 변환기는 내부 문자열 값을 반환합니다. 이 방식 덕분에 DOM 문자열 대신 트러스티드 타입을 점진적으로 도입할 수 있으며, 코드 일부에서만 타입을 생산하고 나머지는 기존 문자열을 계속 사용할 수 있습니다. 즉, 트러스티드 타입은 기존 DOM API와 하위 호환성을 지닙니다.

2.2.1. TrustedHTML

TrustedHTML 인터페이스는 개발자가 인젝션 싱크에 HTML로 출력될 수 있다고 확신하는 문자열을 나타냅니다. 이 객체는 TrustedTypePolicycreateHTML 메서드를 통해 생성되는 문자열 불변 래퍼입니다.

[Exposed=(Window,Worker)]
interface TrustedHTML {
  stringifier;
  DOMString toJSON();
};

TrustedHTML 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.

toJSON() 메서드 단계와 TrustedHTML 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.

2.2.2. TrustedScript

TrustedScript 인터페이스는 개발자가 실행될 수 있다고 확신하는 컴파일되지 않은 스크립트 본문 문자열을 인젝션 싱크에 전달할 수 있게 합니다. 이 객체는 TrustedTypePolicycreateScript 메서드를 통해 생성되는, 문자열을 감싸는 불변 래퍼입니다.

[Exposed=(Window,Worker)]
interface TrustedScript {
  stringifier;
  DOMString toJSON();
};

TrustedScript 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.

toJSON() 메서드 단계와 TrustedScript 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.

2.2.3. TrustedScriptURL

TrustedScriptURL 인터페이스는 개발자가 외부 스크립트 리소스의 URL로 파싱될 수 있다고 확신하는 문자열을 인젝션 싱크에 전달할 수 있게 합니다. 이 객체는 TrustedTypePolicycreateScriptURL 메서드를 통해 생성되는, 문자열을 감싸는 불변 래퍼입니다.

[Exposed=(Window,Worker)]
interface TrustedScriptURL {
  stringifier;
  USVString toJSON();
};

TrustedScriptURL 객체에는 data라는 연결된 문자열이 있습니다. 값은 객체 생성 시 설정되며, 생애주기 동안 변경되지 않습니다.

toJSON() 메서드 단계와 TrustedScriptURL 객체의 stringification behavior 단계는 연결된 data 값을 반환합니다.

2.3. 정책

트러스티드 타입은 오직 문자열을 지정 타입 객체로 변환하는 규칙을 정의한, 사용자가 정의한 불변 정책을 통해서만 생성할 수 있습니다. 정책은 트러스티드 타입이 따라야 할 사용자 지정 프로그래밍 규칙을 지정할 수 있습니다.

작성자는 HTML 문자열에서 자바스크립트 실행을 유발하지 않는 일부 태그/속성만 허용하는 정책을 정의할 수 있습니다. 이 정책으로 생성된 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)처럼 취급할 수 있고, 이는 클로저·내부 함수 변수·모듈을 사용해 통제할 수 있습니다.

하나의 코드 블록 내에서만 접근 가능한, 공격자 제어 입력이 아님을 확인하는 unsafe no-op 정책 예시입니다.
(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)

주어진 TrustedTypePolicyOptions policyOptions 객체의 규칙을 구현하는 정책 객체를 생성합니다. 허용 가능한 정책 이름은 콘텐츠 보안 정책에 의해 제한될 수 있습니다. 정책 이름이 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.

다음 인자를 전달하여 신뢰할 수 있는 타입 정책 생성 알고리즘을 실행한 결과를 반환합니다:

factory
this
policyName
policyName
options
policyOptions
global
this 값의 관련 전역 객체
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나 프로토타입 체인 변조로 객체를 위조하는 경우를 판별하기 위함입니다.

const html = policy.createHTML('<div>');
trustedTypes.isHTML(html); // true

const fake = Object.create(TrustedHTML.prototype);
trustedTypes.isHTML(fake); // false

trustedTypes.isHTML("<div>plain string</div>"); // false
isScript(value)

value가 TrustedScript 인스턴스이고 연관된 data 값이 설정돼 있으면 true를 반환합니다. 그렇지 않으면 false입니다.

isScriptURL(value)

value가 TrustedScriptURL 인스턴스이고 연관된 data 값이 설정돼 있으면 true를 반환합니다. 그렇지 않으면 false입니다.

getPropertyType(tagName, property, elementNs)

작성자가 특정 Element 속성(IDL 속성)에 Trusted Type이 필요한지 확인할 수 있습니다.

이 함수는 다음 알고리즘 결과를 반환합니다:

  1. localNametagNameASCII 소문자 값을 할당합니다.

  2. elementNs가 null 또는 빈 문자열이라면 elementNsHTML 네임스페이스로 설정합니다.

  3. interfacelocalNameelementNs에 대한 엘리먼트 인터페이스로 정합니다.

  4. expectedType을 null로 설정합니다.

  5. 아래 표에서 첫 번째 칸이 "*" 또는 interface 이름이고, 두 번째 칸에 property가 있는 행을 찾습니다. 일치하는 행이 있으면 expectedType에 세 번째 칸 값의 인터페이스 이름을 할당합니다.

    Element Property name TrustedType
    HTMLIFrameElement "srcdoc" TrustedHTML
    HTMLScriptElement "innerText" TrustedScript
    HTMLScriptElement "src" TrustedScriptURL
    HTMLScriptElement "text" TrustedScript
    HTMLScriptElement "textContent" TrustedScript
    "*" "innerHTML" TrustedHTML
    "*" "outerHTML" TrustedHTML
  6. expectedType을 반환합니다.

trustedTypes.getPropertyType('div', 'innerHTML'); // "TrustedHTML"
trustedTypes.getPropertyType('foo', 'bar'); // null
getAttributeType(tagName, attribute, elementNs, attrNs)

작성자가 특정 Element 콘텐츠 속성에 (필요하다면 어떤) Trusted Type이 필요한지 확인할 수 있습니다. 나중에 Element.setAttribute 호출 시 알맞은 인자 타입이 전달되게 합니다.

이 함수는 다음 알고리즘 결과를 반환합니다:

  1. localNametagNameASCII 소문자 값을 할당합니다.

  2. attributeattributeASCII 소문자 값을 할당합니다.

  3. elementNs가 null 또는 빈 문자열이면, elementNsHTML 네임스페이스로 설정합니다.

  4. attrNs가 빈 문자열이면 attrNs를 null로 설정합니다.

  5. interfacelocalNameelementNs에 대한 엘리먼트 인터페이스로 지정합니다.

  6. expectedType을 null로 설정합니다.

  7. attributeData속성을 위한 트러스티드 타입 데이터 가져오기 알고리즘 결과를 다음 인자로 호출해 구합니다:

    • elementinterface

    • attribute

    • attrNs

  8. attributeData가 null이 아니면 expectedTypeattributeData 네 번째 멤버의 인터페이스 이름 값으로 설정합니다.

  9. expectedType을 반환합니다.

trustedTypes.getAttributeType('script', 'src'); // "TrustedScriptURL"
trustedTypes.getAttributeType('foo', 'bar'); // null
emptyHTML, of type TrustedHTML, readonly

TrustedHTML 객체이며, data 값이 빈 문자열로 설정되어 있습니다.

anElement.innerHTML = trustedTypes.emptyHTML; // 정책을 생성할 필요 없음
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

기본 정책 값을 반환합니다.

trustedTypes.defaultPolicy === null;  // true
const dp = trustedTypes.createPolicy('default', {});
trustedTypes.defaultPolicy === dp;  // true

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)이 주어졌을 때 다음 단계를 수행합니다:

  1. allowedByCSPcontent security policy에 의해 Trusted Type policy 생성이 차단되어야 하는지 알고리즘을 global, policyNamefactory생성된 정책 이름 값과 함께 실행한 결과로 설정합니다.

  2. allowedByCSP"Blocked"이면, TypeError를 발생시키고 이후 단계를 중단합니다.

  3. policyNamedefault이고 factory기본 정책 값이 null이 아니면, TypeError를 발생시키고 이후 단계를 중단합니다.

  4. policyTrustedTypePolicy 객체의 새 인스턴스로 설정합니다.

  5. policyname 속성 값을 policyName으로 설정합니다.

  6. policyoptions 값을 «[ "createHTML" -> options["createHTML", "createScript" -> options["createScript", "createScriptURL" -> options["createScriptURL" ]»로 설정합니다.

  7. policyNamedefault인 경우, factory기본 정책 값을 policy로 설정합니다.

  8. Append policyNamefactory생성된 정책 이름에 추가합니다.

  9. policy를 반환합니다.

3.2. Trusted Type 생성

trusted type을 생성하려면 TrustedTypePolicy policy, 타입 이름 trustedTypeName, 문자열 value, 리스트 arguments가 주어지면 다음 단계를 실행합니다:

  1. policyValueget trusted type policy value를 동일한 인수와 추가적으로 true(throwIfMissing)로 실행한 결과로 설정합니다.

  2. 알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.

  3. policyValue를 문자열화한 결과를 dataString으로 설정합니다.

  4. policyValue가 null 또는 undefined이면, dataString을 빈 문자열로 설정합니다.

  5. 타입 이름이 trustedTypeName인 인터페이스의 새 인스턴스를 반환하며, 연결된 데이터 값은 dataString으로 설정합니다.

3.3. Trusted Type 정책 값 가져오기

trusted type policy value를 가져오려면 TrustedTypePolicy policy, 타입 이름 trustedTypeName, 문자열 value, 리스트 arguments, boolean throwIfMissing이 주어지면 아래 단계를 실행합니다:

  1. functionName을 주어진 trustedTypeName에 대해 다음 표를 기반으로 함수 이름으로 설정합니다:

    함수 이름 Trusted Type 이름
    "createHTML" "TrustedHTML"
    "createScript" "TrustedScript"
    "createScriptURL" "TrustedScriptURL"
  2. functionpolicyoptions[functionName]으로 설정합니다.

  3. functionnull이면,

    1. throwIfMissing이 true면 TypeError를 발생시킵니다.

    2. 그렇지 않으면 null을 반환합니다.

  4. args를 « value »로 설정합니다.

  5. Append arguments의 각 항목을 args에 추가합니다.

  6. policyValue콜백 함수 호출functionargs"rethrow"을 넘겨 실행한 결과로 설정합니다.

  7. policyValue를 반환합니다.

3.4. 신뢰된 타입 준수 문자열 가져오기

이 알고리즘은 injection sink에서 사용할 수 있는 문자열을 반환하며, 필요에 따라 일치하는 Trusted Type에서 언래핑할 수 있습니다. 이것은 Trusted Type enforcement 규칙이 준수되었는지 확인합니다.

신뢰된 타입 준수 문자열을 가져오려면 TrustedType 타입(expectedType), 글로벌 오브젝트(global), TrustedType 또는 문자열(input), 문자열(sink), 문자열(sinkGroup)이 주어졌을 때, 다음 단계를 실행합니다:

  1. inputexpectedType의 인스턴스라면, input을 문자열로 변환하여 반환하고 이 단계를 중단합니다.

  2. requireTrustedTypessink 타입이 Trusted Type을 요구하는가? 알고리즘을 global, sinkGroup, true와 함께 실행한 결과로 설정합니다.

  3. requireTrustedTypesfalse라면, input을 문자열로 변환해 반환하고 이 단계를 중단합니다.

  4. convertedInput기본 정책으로 값 처리를 본 알고리즘과 동일한 인수로 실행한 결과로 설정합니다.

  5. 알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.

  6. convertedInputnull 또는 undefined라면, 다음을 실행합니다:

    1. dispositionsink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는지 알고리즘을 global, 문자열화된 inputsource로, sinkGroupsink를 넘겨 실행한 결과로 설정합니다.

    2. disposition“Allowed”라면, input을 문자열로 변환해 반환하고 이후 단계를 중단합니다.

      Note: 이 단계는 기본 정책이 거부되면 보고 모드에서는 무시하고 보고만 하게 합니다.

    3. TypeError를 발생시키고 이후 단계를 중단합니다.

  7. Assert: convertedInputexpectedType의 인스턴스입니다.

  8. convertedInput을 문자열로 변환해 반환합니다.

3.5. 기본 정책으로 값 처리

이 알고리즘은 값을 injection sink에 할당할 때 기본 정책이 존재한다면 해당 정책을 거칩니다.

기본 정책으로 값 처리를 하려면 TrustedType 타입(expectedType), 글로벌 오브젝트(global), TrustedType 또는 문자열(input), 문자열(sink)이 주어졌을 때, 다음 단계를 실행합니다:

  1. defaultPolicyglobaltrusted type policy factory기본 정책 값으로 설정합니다.

  2. policyValueget trusted type policy value를 다음 인수로 실행한 결과로 설정합니다:

    • defaultPolicypolicy

    • 문자열화된 inputvalue

    • expectedType의 타입 이름을 trustedTypeName으로

    • « trustedTypeName, sink »를 arguments

    • false를 throwIfMissing으로

  3. 알고리즘에서 오류가 발생했다면, 오류를 다시 발생시키고 이후 단계를 중단합니다.

  4. policyValue가 null 또는 undefined라면, policyValue를 반환합니다.

  5. dataStringpolicyValue를 문자열화한 결과로 설정합니다.

  6. 타입 이름이 trustedTypeName인 인터페이스의 새 인스턴스를 dataString을 값으로 반환합니다.

3.6. 스크립트 텍스트 준비

스크립트 텍스트를 준비하려면 HTMLScriptElement 또는 SVGScriptElement (script)이 주어졌을 때, 아래 단계를 수행합니다:

  1. sinkscriptHTMLScriptElement이면 "HTMLScriptElement text"로, 아니면 "SVGScriptElement text"로 설정합니다.

  2. scriptscript text 값이 child text content와 다르면, scriptscript text를 아래와 같이 신뢰된 타입 준수 문자열 가져오기 알고리즘의 실행값으로 설정합니다:

    알고리즘에서 오류가 발생하면, 오류를 다시 발생시킵니다.

3.7. 신뢰된 타입 준수 속성 값 가져오기

신뢰된 타입 준수 속성 값을 가져오려면 문자열 attributeName, 문자열 attributeNs, Element elementTrustedType 또는 문자열 newValue가 주어졌을 때, 다음 단계를 수행합니다:

  1. attributeNs가 빈 문자열이면 attributeNs를 null로 설정합니다.

  2. attributeData속성의 신뢰된 타입 데이터 가져오기 알고리즘을 다음 인수로 실행한 결과로 합니다:

    • element

    • attributeName

    • attributeNs

  3. attributeData가 null이면:

    1. newValue가 문자열이면 newValue를 반환합니다.

    2. Assert: newValueTrustedHTML, TrustedScript 또는 TrustedScriptURL입니다.

    3. value의 연결된 데이터를 반환합니다.

  4. expectedTypeattributeData의 네 번째 멤버 값으로 설정합니다.

  5. sinkattributeData의 다섯 번째 멤버 값으로 설정합니다.

  6. 아래 인수로 신뢰된 타입 준수 문자열 가져오기 알고리즘을 실행한 결과를 반환합니다:

알고리즘에서 오류가 발생하면, 오류를 다시 발생시킵니다.

3.8. 속성의 신뢰된 타입 데이터 가져오기

속성의 신뢰된 타입 데이터 가져오기element, attribute, attributeNs가 주어졌을 때, 아래 단계를 수행합니다:

아래에서 사용하는 이벤트 핸들러 콘텐츠 속성 개념은 모호합니다. 이 명세는 이벤트 핸들러 속성을 식별하기 위한 더 나은 메커니즘이 필요합니다. https://github.com/w3c/trusted-types/issues/520 참조.

  1. data를 null로 설정합니다.

  2. 만약 attributeNs가 null이라면, « HTML 네임스페이스, SVG 네임스페이스, MathML 네임스페이스 » 포함한다 element네임스페이스, 그리고 attribute이벤트 핸들러 콘텐츠 속성의 이름인 경우:

    1. (Element, null, attribute, TrustedScript, "Element " + attribute)를 반환합니다.

  3. 아래 표에서 element가 첫 번째 열, attributeNs가 두 번째 열, attribute가 세 번째 열과 일치하는 행을 찾습니다. 일치하는 행이 있으면 data를 그 행으로 설정합니다.

    Element Attribute namespace Attribute local name TrustedType Sink
    HTMLIFrameElement null "srcdoc" TrustedHTML "HTMLIFrameElement srcdoc"
    HTMLScriptElement null "src" TrustedScriptURL "HTMLScriptElement src"
    SVGScriptElement null "href" TrustedScriptURL "SVGScriptElement href"
    SVGScriptElement XLink 네임스페이스 "href" TrustedScriptURL "SVGScriptElement href"
  4. data를 반환합니다.

4. 통합

typedef (TrustedHTML or TrustedScript or TrustedScriptURL) TrustedType;

4.1. HTML과의 통합

WindowWorker 개체에는 trusted type policy factory가 있으며, 이는 TrustedTypePolicyFactory 객체입니다.

4.1.1. WindowOrWorkerGlobalScope 인터페이스 확장

이 문서는 WindowOrWorkerGlobalScope 인터페이스를 HTML에서 정의된 대로 확장합니다:

partial interface mixin WindowOrWorkerGlobalScope {
  readonly attribute TrustedTypePolicyFactory trustedTypes;
};

trustedTypes getter의 단계는 thisrelevant global objecttrusted type policy factory를 반환하는 것입니다.

4.1.2. 스크립트에서의 enforcement

이 문서는 HTMLScriptElement child text content의 설정 방식을 수정하여 애플리케이션이 동적으로 생성된 스크립트를 제어할 수 있게 합니다. 이 작업은 innerTexttextContent 속성을 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. 신뢰된 값이 있는 슬롯

HTMLScriptElementSVGScriptElement 에는 다음이 있습니다:

연관된 문자열 script text.

준수 sink를 통해 설정된 실행할 스크립트 본문을 담고 있는 문자열입니다. script의 child text content와 동등합니다. 초기값은 빈 문자열입니다.

4.1.2.2. innerText IDL 속성

innerText setter의 단계는 다음과 같습니다:

  1. value신뢰된 타입 준수 문자열 가져오기TrustedScript, thisrelevant global object, 주어진 값, HTMLScriptElement innerText, script로 호출한 결과로 설정합니다.

  2. thisscript text 값을 value로 설정합니다.

  3. set the inner text stepsthisvalue로 실행합니다.

innerText getter의 단계:

  1. get the text stepsthis로 실행한 결과를 반환합니다.

4.1.2.3. textContent IDL 속성

textContent setter의 단계는, 주어진 값이 null이면 빈 문자열로 간주한 다음 아래에 설명된 대로 수행합니다.

  1. value신뢰된 타입 준수 문자열 가져오기TrustedScript, thisrelevant global object, 주어진 값, HTMLScriptElement textContent, script로 호출한 결과로 설정합니다.

  2. thisscript text 값을 value로 설정합니다.

  3. set text contentthisvalue로 실행합니다.

textContent getter의 단계:

  1. get text contentthis로 실행한 결과를 반환합니다.

Note: 현재 SVGScriptElement에 해당하는 기능은 추가되지 않았습니다. https://github.com/w3c/trusted-types/issues/512를 참조하세요.

4.1.2.4. text IDL 속성

text setter 단계 알고리즘을 아래와 같이 갱신합니다.

  1. value신뢰된 타입 준수 문자열 가져오기TrustedScript, thisrelevant global object, 주어진 값, HTMLScriptElement text, script로 호출한 결과로 설정합니다.
  2. thisscript text 값을 주어진 값으로 설정합니다.
  3. String replace all을 주어진 값으로 this 안에서 실행합니다.

4.1.2.5. src IDL 속성

src getter의 단계:

  1. elementthis의 get the element 실행 결과로 설정합니다.
  2. contentAttributeValuethis의 get the content attribute 실행 결과로 설정합니다.
  3. contentAttributeValue가 null이면 빈 문자열을 반환합니다.
  4. urlStringelementnode document를 기준으로 contentAttributeValue를 URL 인코딩-파싱-직렬화 한 결과로 설정합니다.
  5. urlString이 failure가 아니면 urlString을 반환합니다.
  6. contentAttributeValue를 스칼라 값 문자열로 변환하여 반환합니다.

src setter의 단계:

  1. value신뢰된 타입 준수 문자열 가져오기TrustedScriptURL, thisrelevant global object, 주어진 값, HTMLScriptElement src, script로 호출한 결과로 설정합니다.
  2. thissrc content attribute를 value로 설정합니다.
4.1.2.6. 파서에서 슬롯 값 설정

이 문서는 HTML 파서가 script가 생성될 때 script text 값을 설정하도록 수정합니다.

The text insertion mode 알고리즘을 다음과 같이 수정합니다:

end tag의 tag name이 "script"인 경우

...

scriptscript 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 알고리즘의 처음 몇 단계를 아래와 같이 수정합니다:

  1. elalready started가 true면 return합니다.

  2. parser documentelparser document로 설정합니다.

  3. elparser document를 null로 설정합니다.

    이렇게 하면 파서가 삽입한 script 요소가 파서가 이를 실행하려 할 때(예: 비었거나 지원되지 않는 스크립팅 언어일 때) 실행에 실패하면, 다른 스크립트가 나중에 이를 변경하여 다시 실행할 수 있습니다.

  4. parser document가 null이 아니고, elasync 속성을 가지고 있지 않으면 elforce async를 true로 설정합니다.

    이렇게 하면 파서가 삽입한 script 요소가 실행에 실패해도, 나중에 동적으로 업데이트되어 실행될 경우 async 속성이 없어도 비동기로 실행됩니다.

  5. el에 대해 스크립트 텍스트 준비 알고리즘을 실행합니다. 알고리즘에서 오류가 발생했다면 return 합니다.

  6. source textelchild text content. script text 값.

  7. ...

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만 명세되어 있습니다.

지시어의 namevalue 구문은 다음 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"
DOM XSS injection sink에서 Trusted Types를 enforcement합니다.
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 함수를 반드시 거치도록 보장합니다.

  1. requesturlscheme"javascript"가 아니면 "Allowed"를 반환하고 더 이하 단계를 중단합니다.

  2. urlStringURL serializerrequesturl에 실행한 결과로 설정합니다.

  3. encodedScriptSourceurlString에서 선행 "javascript:"를 제거한 값으로 설정합니다.

  4. convertedScriptSource기본 정책으로 값 처리 알고리즘에 다음 인수를 넘겨 실행한 결과로 설정합니다:

    알고리즘에서 오류가 발생하거나 convertedScriptSourceTrustedScript 객체가 아니면 "Blocked"를 반환하고, 추가 단계를 중단합니다.

  5. urlString을 stringified convertedScriptSource 앞에 "javascript:"를 붙여서 만듭니다.

  6. newURLURL parserurlString에 실행한 결과로 설정합니다. 파서가 failure를 반환하면 "Blocked"를 반환하고 추가 단계를 중단합니다.

  7. requesturlnewURL로 설정합니다.

    Note: pre-navigation check에서 javascript: URL에는 다른 CSP 지시어가 적용되지 않습니다. javascript: URL을 확인하는 다른 지시어는, 나중에 inline check 단계에서 수정된 URL에 대해 동작합니다.

  8. "Allowed"를 반환합니다.

4.3.2. trusted-types 지시어

이 문서는 trusted-types라는 새로운 Content Security Policy 지시어를 정의합니다. trusted-types 지시어는 Trusted Type 정책 생성 제어에 사용됩니다.

지시어의 namevalue 구문은 아래 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'"
sink에서 타입이 enforcement되고, "one"과 "two" 두 정책만 생성할 수 있습니다.
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types one two
지시어 은 정책을 생성할 수 없음을 의미하며, sink에서는 Trusted Type 값만 기대합니다. 즉 DOM XSS injection sink를 전혀 사용할 수 없습니다.
Content-Security-Policy: trusted-types; require-trusted-types-for 'script'

키워드 'none'을 사용하여 위와 같이 명시적으로 표현할 수 있습니다:

Content-Security-Policy: trusted-types 'none'; require-trusted-types-for 'script'

키워드 'allow-duplicates'는 이미 사용된 이름을 가진 정책도 생성할 수 있도록 허용합니다.

Content-Security-Policy: trusted-types foo bar 'allow-duplicates'

default라는 이름의 정책이 목록에 있으면, 이는 기본 정책을 의미합니다. 모든 문자열이 injection sink에 전달될 때 바로 거부되는 대신, 반드시 해당 정책을 거칩니다.

Content-Security-Policy: trusted-types one two default

4.3.3. Sink 타입이 Trusted Types를 요구하는가?

이 알고리즘은 injection sinkTrusted Type을 필요로 하면 true를, 그렇지 않으면 false를 반환합니다.

Sink 타입이 Trusted Types를 요구하는가? 알고리즘은 global object (global), 문자열 (sinkGroup), 불리언 (includeReportOnlyPolicies)가 주어졌을 때, 다음 단계를 수행합니다:

  1. globalCSP list의 각 policy에 대해:

    1. policydirective setdirective가 없거나 그 name"require-trusted-types-for"가 아니라면, 다음 policy로 넘어감.

    2. directivepolicydirective set에서 이름이 "require-trusted-types-for"directive로 설정함.

    3. directivevaluetrusted-types-sink-groupsinkGroup과 일치하는 것이 없으면, 다음 policy로 넘어감.

    4. enforcedpolicydisposition"enforce"이면 true, 아니면 false로 설정함.

    5. enforced가 true이면 true를 반환.

    6. includeReportOnlyPolicies가 true이면 true를 반환.

  2. false 반환.

4.3.4. Sink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는가?

이 알고리즘은 injection sinkTrusted Type을 필요로 하면 "Blocked"를, 그렇지 않으면 "Allowed"를 반환합니다.

Sink 타입 불일치 위반이 Content Security Policy에 의해 차단되어야 하는가? 알고리즘은 global object (global), 문자열 (sink), 문자열 (sinkGroup), 문자열 (source)가 주어지면 다음 단계를 수행합니다:

  1. result"Allowed"로 설정함.

  2. samplesource로 설정함.

  3. sink"Function"이면,

    1. sample"function anonymous"로 시작하면, sample에서 이를 제거함.

    2. 그렇지 않고 sample"async function anonymous"로 시작하면, sample에서 이를 제거함.

    3. 그렇지 않고 sample"function* anonymous"로 시작하면, sample에서 이를 제거함.

    4. 그렇지 않고 sample"async function* anonymous"로 시작하면, sample에서 이를 제거함.

  4. globalCSP list의 각 policy에 대해:

    1. policydirective setdirective가 없거나 name이 "require-trusted-types-for"가 아니라면 다음 policy로 넘어감.

    2. directivepolicydirective set에서 이름이 "require-trusted-types-for"directive로 설정.

    3. directivevaluetrusted-types-sink-groupsinkGroup과 일치하는 것이 없으면 다음 policy로 넘어감.

    4. violationCreate a violation object for global, policy, and directiveglobal, policy, "require-trusted-types-for"를 넘겨 실행한 결과로 설정.

    5. violationresource"trusted-types-sink"로 설정.

    6. trimmedSamplesample의 첫 40자 만큼의 부분 문자열로 설정.

    7. violationsample"|" 구분자로 « sink, trimmedSample »를 연결한 값으로 설정.

    8. Report a violationviolation으로 실행.

    9. policydisposition"enforce"이면 result"Blocked"로 설정.

  5. result 반환.

4.3.5. Trusted Type 정책 생성을 Content Security Policy에서 차단해야 하는가?

이 알고리즘은 TrustedTypePolicy 를 생성하면 안 되는 경우 "Blocked"를, 그렇지 않으면 "Allowed"를 반환함.

Trusted Type 정책 생성을 Content Security Policy에서 차단해야 하는가? 알고리즘은 global object (global), 문자열 (policyName), 문자열 리스트 (createdPolicyNames)가 주어졌을 때, 아래 단계를 실행합니다:

  1. result"Allowed"로 설정함.

  2. globalCSP list의 각 policy에 대해:

    1. createViolation을 false로 설정.

    2. policydirective setdirective가 없거나 name이 "trusted-types"가 아니라면, 다음 policy로 넘어감.

    3. directivepolicydirective set에서 이름이 "trusted-types"directive로 설정함.

    4. directivevaluett-keyword'none'과 일치하는 것만 포함하면 createViolation을 true로 설정.

      Note: 다른 키워드/정책명이 있으면 'none' 키워드는 무시됩니다.

    5. createdPolicyNamespolicyName이 포함되어 있고 directivevaluett-keyword'allow-duplicates'에 해당하는 값이 없으면 createViolation을 true로 설정.

      Note: trusted-types policyA policyB 'allow-duplicates'는 동일 이름 정책 중복 생성을 허용합니다.

    6. directivevaluepolicyName과 값이 같은 tt-policy-name이 없고 tt-wildcard가 없으면 createViolation을 true로 설정.

      Note: trusted-types *는 임의의 고유 이름 정책 생성을 허용합니다. 중복된 이름 허용하려면 trusted-types * 'allow-duplicates' 또는 아예 trusted-types 지시어를 생략합니다.

    7. createViolation이 false면 다음 policy로 넘어감.

    8. violationCreate a violation object for global, policy, and directiveglobal, policy, "trusted-types"를 넘겨 실행한 결과로 설정.

    9. violationresource"trusted-types-policy"로 설정함.

    10. violationsamplepolicyName의 최대 40자 부분 문자열로 설정함.

    11. Report a violationviolation으로 실행.

    12. policydisposition"enforce"이면 result"Blocked"로 설정.

  3. 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에 문자열을 전달할 때 기본 정책 실행, 위반 생성, 값 거부가 일어나지 않아야 합니다.

적합성

문서 관례

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

이 명세의 모든 텍스트는 명시적으로 비규범임을 나타낸 섹션, 예시, 노트 외에는 규범적입니다. [RFC2119]

이 명세의 예시는 “예를 들어(for example)”라는 말로 시작되거나, 규범적 텍스트와 class="example"로 분리되어 다음과 같이 제시됩니다:

다음은 참고용 예시입니다.

참고 노트는 “Note”라는 단어로 시작하며, 규범적 텍스트와 class="note"로 분리되어 이와 같이 제시됩니다:

Note, 이것은 참고용 노트입니다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같은 “Tests” 블록으로 문서화될 수 있습니다. 이러한 모든 블록은 비규범적입니다.


적합성 알고리즘

알고리즘의 일부로 서술형 명령문(예: "선행 공백을 모두 제거하라" 또는 "false를 반환하고 이 단계를 중단하라")는 해당 알고리즘에 소개된 주요 단어("must", "should", "may" 등)의 의미로 해석해야 합니다.

알고리즘이나 구체적인 단계로 표현된 적합성 요구 사항은 결과가 동등하다면 어떤 방식으로든 구현할 수 있습니다. 특히, 본 명세에 정의된 알고리즘은 이해하기 쉽도록 의도된 것이며 반드시 성능을 고려한 것은 아닙니다. 구현자는 최적화를 권장합니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고문헌

[CSP3]
Mike West; Antonio Sartori. Content Security Policy Level 3. 11 July 2025. WD. URL: https://www.w3.org/TR/CSP3/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[Fetch]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. 4 December 2024. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 4 October 2018. CR. URL: https://www.w3.org/TR/SVG2/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참고문헌

[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[HTML-DESIGN-PRINCIPLES]
Anne van Kesteren; Maciej Stachowiak. HTML Design Principles. 26 November 2007. WD. URL: https://www.w3.org/TR/html-design-principles/
[HTML5]
Ian Hickson; et al. HTML5. 27 March 2018. REC. URL: https://www.w3.org/TR/html5/

이슈 색인

아래에서 사용하는 이벤트 핸들러 콘텐츠 속성 개념은 모호합니다. 이 명세는 이벤트 핸들러 속성을 식별하는 더 나은 메커니즘이 필요합니다. https://github.com/w3c/trusted-types/issues/520 참조.
위 알고리즘은 script element의 내용이 파싱 도중 변경되는 경우를 고려하지 않습니다. 구현자는 이 케이스를 보호해야 합니다. https://github.com/w3c/trusted-types/issues/507 참조.
SVG script elements 처리에 대한 정식 정의가 없습니다. 하지만 구현에서는 SVGScriptElement 처리도 유사하게 변경해야 합니다.
SVG script elements 처리에 대한 정식 정의가 없습니다. 하지만 구현에서는 SVGScriptElement 처리도 유사하게 변경해야 합니다.
보안 정책 설계는 외부 문서를 참조하세요.
MDN

TrustedHTML/toJSON

In only one current engine.

FirefoxNoneSafariNoneChrome90+
Opera?Edge90+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedHTML/toString

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedHTML

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedScript/toJSON

In only one current engine.

FirefoxNoneSafariNoneChrome90+
Opera?Edge90+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedScript/toString

In only one current engine.

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

TrustedScriptURL/toString

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedScript

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedScriptURL/toJSON

In only one current engine.

FirefoxNoneSafariNoneChrome90+
Opera?Edge90+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedScriptURL

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicy/createHTML

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicy/createScript

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicy/createScriptURL

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicy/name

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicy

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/createPolicy

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/defaultPolicy

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/emptyHTML

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/emptyScript

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/getAttributeType

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/getPropertyType

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/isHTML

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/isScript

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory/isScriptURL

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

TrustedTypePolicyFactory

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Headers/Content-Security-Policy/require-trusted-types-for

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Headers/Content-Security-Policy/trusted-types

In only one current engine.

FirefoxNoneSafariNoneChrome83+
Opera?Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone