1. 소개
웹 플랫폼은 점점 더 많은 기능과 API를 제공하여, 더 풍부한 기능, 더 나은 개발자 경험, 그리고 향상된 성능을 제공합니다. 하지만 개발자가 애플리케이션 내에서 일부 브라우저 기능과 API의 동작을 선택적으로 활성화, 비활성화 또는 수정할 수 있는 기능이 부족합니다:
- 개발자는 보안 또는 성능상의 이유로, 자신의 애플리케이션에서 특정 브라우저 기능 및 API 접근을 선택적으로 비활성화하여, 자체 및 서드파티 콘텐츠가 원하지 않거나 예기치 않은 동작을 유발하는 것을 방지하고자 할 수 있습니다.
- 개발자는 기본적으로 비활성화된 일부 브라우저 기능 및 API 접근을 선택적으로 활성화하고자 할 수 있습니다. 예를 들어 일부 기능은 내장된 환경에서 명시적으로 활성화하지 않으면 기본적으로 비활성화될 수 있으며, 일부 기능은 다른 정책 요구 사항이 적용될 수 있습니다.
- 개발자는 정책을 활용하여 클라이언트나 임베더에게 특정 기능 및 API 사용(또는 사용하지 않음)에 대한 약속을 명시하고자 할 수 있습니다. 예를 들어, 브라우저에서 특정 유형의 "빠른 경로" 최적화를 활성화하거나, 다른 임베더(예: 다양한 소셜 네트워크, 검색 엔진 등)가 정한 요구사항 준수에 대한 약속을 명시할 수 있습니다.
이 명세는 위와 같은 사용 사례를 해결하기 위한 정책 메커니즘을 정의합니다.
이 명세는 이전에 Feature Policy라는 이름을 사용했습니다.
2. 예시
SecureCorp Inc.는 애플리케이션 내에서 Fullscreen 및 Geolocation API의 사용을 비활성화하고자 합니다. 다음과 같은 HTTP 응답 헤더를 전달하여 권한 정책을 정의할 수 있습니다:
Permissions-Policy: fullscreen=(), geolocation=()
빈 origin 목록을 명시하면, 지정된 기능은 모든 문서(중첩 문서 포함)에서 origin과 관계없이 비활성화됩니다.
Geolocation은 모든 교차 출처 프레임에서 기본적으로 비활성화되어 있습니다. FastCorp Inc.는 특정 교차 출처 iframe에서 geolocation을 활성화하고자
하며, iframe 요소에 "allow
" 속성을 추가하여 이를 할 수 있습니다:
<iframe src="https://other.com/map" allow="geolocation"></iframe>
iframe 속성을 통해 특정 프레임에만 기능을 선택적으로 활성화할 수 있으며, 동일 origin의 문서를 포함하더라도 다르게 동작할 수 있습니다.
SecureCorp Inc.는 모든 후손 navigable에서 자신의 origin과
"https://example.com
" origin을 제외하고 Geolocation API의 사용을 완전히 비활성화하고자 합니다. 공격자가
SecureCorp 페이지에 자신의 iframe을 임베드하더라도 이를 보장할 수 있습니다. 다음과 같은 HTTP 응답 헤더를 전달하여 Geolocation에 제한된 권한 정책을
정의할 수 있습니다:
Permissions-Policy: geolocation=(self "https://example.com")
허용 목록은 하나 이상의 origin으로 구성된 리스트로,
애플리케이션의 origin(옵션으로 "self
" 키워드 포함)과 서드파티 origin을 포함할 수 있습니다.
이 정책이 적용되면, iframe의 "allow
" 속성을 통해 특정 프레임에 geolocation을 허용할 수 있지만, 실제로 해당 API를 사용할 수 있는
프레임은 http://example.com 또는 SecureCorp 자체의 콘텐츠만 가능합니다.
SecureCorp Inc.가 도메인 구조를 재정비하고, Geolocation API 사용을 자신의 origin("https://example.com
")뿐만
아니라 세 개의 서브도메인("https://geo.example.com
", "https://geo2.example.com
",
"https://new.geo2.example.com
")에도 위임해야 하는 상황입니다. 동시에 다른 브라우징 컨텍스트에서는 Geolocation API
사용을 비활성화해야 합니다. 다음과 같은 HTTP 응답 헤더를 전달하여 이를 달성할 수 있습니다:
Permissions-Policy: geolocation=(self "https://example.com" "https://geo.example.com" "https://geo2.example.com" "https://new.geo2.example.com")
이 방법도 가능하지만, SecureCorp Inc.가 "https://example.com
"의 모든 서브도메인에 위임해도 안전하다고 판단된다면, HTTP 응답
헤더를 다음과 같이 설정할 수 있습니다:
Permissions-Policy: geolocation=(self "https://example.com" "https://*.example.com")
위의 헤더는 "https://geo.example.com
", "https://geo2.example.com
",
"https://new.geo2.example.com
"뿐만 아니라 "https://example.com
"의 모든 서브도메인에서도
Geolocation API 사용을 허용합니다. "https://example.com
"은 허용 목록의 "https://*.example.com
" 항목에
포함되지 않으므로 반드시 별도로 추가해야 합니다.
SecureCorp Inc.가 서비스를 재구성하여 Geolocation API 사용을 자신의 origin("https://example.com
")뿐만 아니라
세 개의 비표준 포트("https://example.com:444
", "https://example.com:445
",
"https://example.com:446
")에도 위임해야 하는 상황입니다. 동시에 다른 브라우징 컨텍스트에서는 Geolocation API 사용을
비활성화해야 합니다. 다음과 같은 HTTP 응답 헤더를 전달하여 이를 달성할 수 있습니다:
Permissions-Policy: geolocation=(self "https://example.com" "https://example.com:444" "https://example.com:445" "https://example.com:446")
이 방법도 가능하지만, SecureCorp Inc.가 "https://example.com
"의 모든 포트에 위임해도 안전하다고 판단된다면, HTTP 응답
헤더를 다음과 같이 설정할 수 있습니다:
Permissions-Policy: geolocation=(self "https://example.com:*")
위의 헤더는 "https://example.com:444
", "https://example.com:445
",
"https://example.com:446
"뿐만 아니라 "https://example.com
"의 모든 포트에서 Geolocation
API 사용을 허용합니다.
JSPlaygroundCorp Inc.는 사용자 생성 웹 애플리케이션을 호스팅하려고 하지만, 브라우저가 각 애플리케이션의 권한을 서로 분리하여 관리하기를 원합니다. 이를 위해 각 웹 콘텐츠 또는 생성자마다 개별 서브도메인을 생성하고, 이를 최상위 문서로 탐색하면(프레임워크와 사용자 콘텐츠는 동일 origin iframe으로 분리 가능) 목적을 달성할 수 있습니다.
브라우저에서 사용자는 상호작용하는 도메인(즉, 최상위 도메인)에 권한을 부여하므로, 이는 반드시 필요합니다.
이 경우 JSPlaygroundCorp는 자신의 도메인에서
allow
속성을 사용해 사용자 생성 웹 애플리케이션을 iframe으로 감싸는 것을 피해야 합니다. 그렇지 않으면 자신의 도메인에 모든 권한이 부여됩니다.
PlatformCorp Inc.는 최상위 도메인 내에서 빌드용 임베더블 서드파티 컴포넌트나 게임을 제공하는 마켓플레이스를 운영하려고 합니다. 강력한 기능인 getUserMedia()
API 사용을 책임감 있게 위임하고자 하며, 각 컴포넌트 애플리케이션의 기능 필요성을 직접 추적하고, 맞춤형 "설치" UX를 통해 최종 사용자가 권한을 직접 제어할 수 있도록
합니다.
카메라와 마이크는 모든 교차 출처 프레임에서 기본적으로 비활성화되어 있습니다. 각 서드파티 컴포넌트는 별도의 서브도메인을 가지고, 교차 출처 iframe으로 임베드될 수 있습니다.
PlatformCorp는
allow
속성을
iframe
요소에 설정하여 각 서브도메인에 카메라 또는 마이크 접근 권한을 위임할 수 있습니다.
예를 들어, "app1" 컴포넌트는 카메라 접근, "app2"는 마이크 접근, "app3"은 둘 다 접근해야 한다면 다음과 같이 설정할 수 있습니다:
<iframe allow="camera https://app1.site.com https://app3.site.com; microphone https://app2.site.com https://app3.site.com" src="https://doc1.site.com" sandbox="allow-same-origin allow-scripts"> </iframe>
iframe 속성을 통해 특정 프레임에만 기능을 선택적으로 활성화할 수 있으며, 동일 origin의 문서를 포함하더라도 다르게 동작할 수 있습니다. 실제로 sandbox 토큰 목록은 더 길 수 있습니다.
브라우저는 일반적으로 사용자가 최상위 도메인에 권한을 부여하기 때문에, 사용자가 이미 PlatformCorp를 신뢰하는 경우 컴포넌트에서 카메라 또는 마이크 접근을 요청할 때 추가 권한 프롬프트가 뜨지 않을 수 있습니다.
3. 기타 및 관련 메커니즘
[HTML5]는
sandbox
속성을
iframe
요소에 정의하여, 개발자가 잠재적으로 신뢰할 수 없는 콘텐츠의 능력을 제한함으로써(예: 폼 제출 방지, 스크립트 및 플러그인 실행 방지 등) 위험을 줄일 수 있게 합니다. sandbox
지시문은 [CSP2]에서
확장되어, 어떤 리소스든(프레임 여부와 무관하게) 동일한 제약을 요청할 수 있게 합니다(예: HTTP 응답 헤더
Content-Security-Policy: sandbox
사용). 이러한 메커니즘을 통해 개발자는 다음을 할 수 있습니다:
- CSP를 통해 어떤 리소스든 샌드박스 정책을 설정 및 맞춤화
- 애플리케이션 내 각
iframe
요소에 개별 샌드박스 정책을 설정 및 맞춤화
하지만 위 메커니즘에는 몇 가지 제한이 있습니다: 개발자는 모든 컨텍스트에 자동으로 정책을 적용할 수 없으므로 일부 경우(예: 개발자가 제어하지 않는 서드파티 콘텐츠가 프레임을 삽입하는 경우)에 일관적으로 강제하기 어렵거나 불가능합니다. 기본적으로 비활성화된 기능을 선택적으로 활성화할 수 있는 메커니즘이 없습니다. 샌드박스 메커니즘은 모든 샌드박스 기능을 자동으로 비활성화하며, 개발자가 각 기능을 다시 활성화해야 하므로, 샌드박스 기능 집합을 확장하는 것은 호환성 위험이 큽니다.
Permissions Policy는 샌드박스 메커니즘과 함께 사용하도록 설계되어(이미 샌드박스에서 제어되는 기능을 중복 제어하지 않음), 위의 제한을 해결할 수 있는 확장 가능한 메커니즘을 제공합니다.
4. 프레임워크
4.1. 정책 제어 기능
정책 제어 기능은 권한 정책에서 참조하여 문서에서 활성화 또는 비활성화할 수 있는 API 또는 동작입니다.
정책 제어 기능은 토큰(정책 지시문에서 사용되는 문자열)으로 식별됩니다.
각 정책 제어 기능은 기본 허용 목록을 가지며, 최상위 traversable 문서에서 해당 기능의 사용 가능 여부와 자식 navigable에서의 접근 상속 방식을 정의합니다.
사용자 에이전트는 지원 기능 집합을 가지며, 이는 정책을 통해 제어할 수 있는 기능 집합입니다. 사용자 에이전트는 모든 기능을 지원할 필요는 없습니다.
4.2. 정책
빈 권한 정책은
권한 정책으로, 상속 정책에 모든 지원 기능에 대해 "Enabled
"가
포함되어 있고, 선언된 정책의 선언 및 리포트 구성이 모두 빈 순서있는 맵인 경우입니다.
4.3. 상속 정책
특정 기능의 상속 정책 feature는 상속 정책에서 키가 feature인 값입니다. 권한 정책이 초기화되면 상속 정책에 각 지원 기능에 대한 값이 포함됩니다.
생성 및 탐색 시, 각 Document
는
부모 프레임에서 정책을 상속받으며, Document
가
최상위 traversable에 있을 때는 각 정책 제어 기능에 대한
정의된 기본값을 상속받습니다. 이 상속 정책은 각 기능의 초기 상태("Enabled
" 또는 "Disabled
")와 Document
내 선언된 정책에서 해당 기능을 제어할 수 있는지 결정합니다.
Document
가
최상위 traversable에 있을 경우, 상속 정책은 각 기능에 대해 정의된 기본값을
기반으로 합니다.
Document
가
자식 navigable에 있을 경우, 상속 정책은 부모 문서의 권한 정책과 자식 navigable의 컨테이너 정책을 기반으로 합니다.
4.4. 헤더 정책
헤더 정책은 문서와 함께 HTTP 헤더를 통해 전달되는 정책 지시문의 목록입니다. 이것은 문서의 권한 정책의 선언된 정책을 형성합니다.
4.5. 컨테이너 정책
헤더 정책 외에도, 각 자식 내비게이블은 컨테이너 정책을 가지며, 이는 정책 지시문이고 비어 있을 수도 있습니다. 컨테이너 정책은 내비게이블 컨테이너의 속성에 의해 설정될 수 있습니다.
컨테이너 정책은 자식 내비게이블에 로드되는 Document
의
상속 정책에 영향을 미칩니다. (자세한 내용은 § 9.7 컨테이너에서 기능에
대한 상속 정책 정의 참고).
iframe
의
allowfullscreen
와
allow
속성에 의해 간접적으로 설정됩니다. 향후 명세 개정에서는 전체 컨테이너 정책을 명시적으로 선언할 수 있는 메커니즘이 도입될 수 있습니다.
4.6. 정책 지시문
정책 지시문은 순서 있는 맵으로, 정책 제어 기능을 해당 허용 목록의 origin과 매핑합니다.
정책 지시문은 HTTP 헤더에서 sf-dictionary 구조의 직렬화로 표기되며, HTML 속성에서는 ASCII 직렬화로 표기됩니다.
4.7. 허용 목록
권한 정책 허용 목록은 개념적으로 origin의 집합입니다. 허용 목록은 다음 중 하나일 수 있습니다:
- 특별 값
*
, 모든 origin을 의미합니다. - 다음 항목을 포함하는 구조체:
- expressions, permissions-source-expression의 순서 있는 집합
- self-origin, origin 또는
null
- src-origin, origin 또는
null
'self'
, 'src'
, 'none'
키워드는 허용 목록의 헤더 및 속성 문자열 표현에서 등장할 수
있습니다. 이 키워드들은 파싱 시 항상 컨텍스트에서 해석되며, 참조하는 origin만 허용 목록에 저장됩니다. 키워드 자체는 허용 목록의 일부가 아닙니다.
허용 목록이 origin origin에 일치하는지 판단하려면 다음 단계를 따릅니다:
참고: CSP 와일드카드 매칭 방식은 HTTPS 스킴이 필요하므로 사용하지 않습니다.
-
허용 목록의 self-origin이 null이 아니고 origin과 동일 origin-domain이면 true를 반환합니다.
-
허용 목록의 src-origin이 null이 아니고 origin과 동일 origin-domain이면 true를 반환합니다.
-
origin이 불투명 origin이면 false를 반환합니다.
-
url을 url parser에 origin의 직렬화로 호출한 결과로 설정합니다.
-
각 permissions-source-expression item에 대해 허용 목록의 expressions에서 반복:
-
Does url match expression in origin with redirect count?를 url, item, origin, 0 으로 실행한 결과가 true이면 true를 반환합니다.
-
-
false를 반환합니다.
4.8. 기본 허용 목록
모든 정책 제어 기능은 기본 허용 목록을 갖습니다. 기본 허용 목록은 Document
가
선언된 정책 없이 최상위 내비게이블에 있을 때 해당 기능의 허용 여부와, 기능 접근이 자식 내비게이블의 문서로 자동 위임되는지 여부를 결정합니다.
기본 허용 목록은 다음 값 중 하나입니다:
*
- 기능은 기본적으로 최상위 내비게이블 및 모든 자식 내비게이블의
Document
에서 허용됩니다. 컨테이너 정책을 내비게이블 컨테이너에 명시적으로 공급하여(또는 내비게이블에Document
를 적절한Permissions-Policy
헤더로 전달) 자식 내비게이블에서 비허용할 수 있습니다. 'self'
- 기능은 기본적으로 최상위 내비게이블의 문서 및 자식 내비게이블의 문서가 부모의 문서와 동일 origin일 때 허용됩니다(부모
Document
에서 허용된 경우). 문서가 부모의 문서와 교차 origin인 자식 내비게이블에서는 기본적으로 비허용됩니다.
5. 권한 정책 직렬화
5.1. HTML 속성 직렬화
정책 지시문은 HTML 속성에서 아래 ABNF와 같이 ASCII 직렬화로 표현됩니다:
serialized-permissions-policy = serialized-policy-directive *(";" serialized-policy-directive) serialized-policy-directive = feature-identifier RWS allow-list feature-identifier = 1*( ALPHA / DIGIT / "-") allow-list = allow-list-value *(RWS allow-list-value) allow-list-value = permissions-source-expression / "*" / "'self'" / "'src'" / "'none'" permissions-source-expression = scheme-source / host-source
5.2. 구조화된 헤더 직렬화
정책 지시문은 HTTP 헤더에서 Structured Fields로 표현됩니다. [RFC8941]이 표현에서 정책 지시문은 Dictionary로 표현됩니다.
각 Dictionary Member는 기능을 허용 목록과 연결합니다. Member 이름은 반드시 Token이어야 합니다. 만약 토큰이 사용자 에이전트의 지원 기능 중 하나가 아니면, 해당 Dictionary Member는 처리 단계에서 무시됩니다.
Member 값은 허용 목록을 나타내며, 다음 중 하나여야 합니다:
-
ASCII permissions-source-expression을 포함하는 문자열
-
Token
*
-
Token
self
-
위 항목들 중 0개 이상을 포함하는 Inner List
Member 값에는 "report-to"
라는 이름의 파라미터가 있을 수 있고, 값은 반드시 문자열이어야 합니다. 다른 파라미터는 모두 무시됩니다.
Inner List 안의 다른 항목은 처리 단계에서 무시되며, Member 값은 해당 항목이 없는 것처럼 처리됩니다. 다른 형태의 Member 값은 전체 Dictionary Member가 처리 단계에서 무시되게 합니다.
6. 전달
6.1. `Permissions-Policy
` HTTP 헤더
필드
Permissions-Policy
HTTP 헤더 필드는 응답 (서버 → 클라이언트)에서 클라이언트가 적용해야 하는 권한 정책을 전달하는
데 사용될 수 있습니다.
Permissions-Policy
는 구조화된 헤더입니다. 값은 반드시
딕셔너리여야 합니다. ABNF는 다음과 같습니다:
PermissionsPolicy = sf-dictionary
딕셔너리의 의미론은 § 5.2 구조화된 헤더 직렬화에서 정의됩니다.
처리 단계는 § 9.2 사전과 출처로 정책 구성에서 정의됩니다.
6.2.
iframe
요소의 allow
속성
iframe
요소는
allow
속성을 가지며, 이 속성에는 ASCII-직렬화 정책 지시문이 포함됩니다.
속성에 명시된 기능의 허용 목록은 비어 있을 수
있습니다. 이 경우 허용 목록의 기본 값은 'src'
이며, 이는 iframe의
src
속성에 있는 URL의 origin을 나타냅니다.
비어 있지 않은 경우,
allow
속성은 인식된 기능 각각에 대한 허용 목록을
iframe
요소의 콘텐츠 내비게이블의 컨테이너 정책에 추가하게 됩니다(생성 시).
6.3. 레거시 기능 지원 추가 속성
Permissions Policy가 제어하는 일부 기능은 기존 iframe 속성으로 정의되어 있습니다. 이 명세는 해당 속성들이
iframe
의
콘텐츠 내비게이블의 컨테이너 정책에 영향을 주도록 재정의합니다.
6.3.1. allowfullscreen
allowfullscreen
iframe
속성은 requestFullscreen()
접근을 제어합니다.
iframe 요소에
allow
속성이 있고 그 값에 "fullscreen
" 토큰이 포함되어 있다면,
allowfullscreen
속성은 아무 효과도 없어야 합니다.
그 외의 경우,
allowfullscreen
속성이
iframe
에
있으면, 해당 요소의 허용 목록에
"fullscreen
" 기능에 대해 *
가 추가되고, 이는
iframe
요소의 콘텐츠 내비게이블의 컨테이너 정책에 추가됩니다(생성 시).
<iframe allow="fullscreen">
의 동작과 다르며, 기존 allowfullscreen
사용과의
호환성을 위해 정의된 것입니다. allow="fullscreen"
과 allowfullscreen
이 모두 iframe 요소에
있으면, allow="fullscreen"
의 더 제한적인 허용 목록이 사용됩니다.
7. 스크립트에서의 정책 내성
7.1. 개요
문서에서 현재 적용 중인 정책은 스크립트를 통해 관찰할 수 있습니다. 이는 어떤 기능이 활성화되어 있는지 여부를 외부적으로 판단할 수 없을 때, 어떤 사용자 인터페이스를 보여줄지 결정하는 데 사용할 수 있습니다. (일부 기능은 관찰 가능한 실패 동작이 없거나, 기능 감지시 원하지 않는 부작용이 있을 수 있습니다.)
문서와 iframe 모두 PermissionsPolicy
객체를 제공하며, 이를 통해 적용된 권한 정책을 검사할 수 있습니다.
7.1.1. 문서 정책
현재 적용 중인 정책을 가져오려면 document.permissionsPolicy
를 사용하세요. 이는 PermissionsPolicy
객체를 반환하며, 아래와 같은 용도로 사용할 수 있습니다:
-
현재 문서에서 특정 기능의 상태(허용 또는 거부)를 질의할 수 있습니다.
-
현재 문서에서 사용 가능한 모든 기능(허용 여부와 관계없이)의 목록을 얻을 수 있습니다.
-
현재 문서에서 허용된 모든 기능의 목록을 얻을 수 있습니다.
-
현재 문서에서 특정 기능의 허용 목록을 얻을 수 있습니다.
<!doctype html> <script> const policy = document.permissionsPolicy; // 이 문서에서 WebUSB를 사용할 수 있으면 true입니다. const can_use_usb = policy.allowsFeature('usb'); // https://example.com에서 새로운 프레임이 WebXR을 사용할 수 있다면 true입니다. if (policy.allowsFeature('xr-spatial-tracking', 'https://example.com')) { // https://example.com 프레임 생성 UI 표시 } else { // 대체 UI 표시 } // 결제 요청이 허용된 origin 목록을 가져옵니다. 결과는 명시적인 origin 리스트이거나, 모든 origin이 허용되면 ['*'] 단일 원소 리스트입니다. const allowed_payment_origins = policy.getAllowlistForFeature('payment'); // 이 문서에서 지원되는 모든 기능(허용되지 않은 기능 포함)의 목록을 가져옵니다. 결과는 각 기능을 나타내는 문자열 배열입니다. const all_features = policy.features(); if (all_features.includes('geolocation')) { // 서드파티 지도 서비스에 자식 프레임 추가 } </script>
7.1.2. 프레임 정책
iframe 요소에 적용된 정책을, 이를 포함하는 문서에서 검사할 수도 있습니다. 이 경우의 정책 객체는 해당 프레임의 관찰 가능한 정책을 나타내며, 이는 현재 문서와 iframe 요소의 속성만을 기반으로 합니다. 실제로 프레임 내에서 기능이 허용되는지 여부를 알 수는 없으며, 프레임 내의 문서가 HTTP 헤더로 자체 정책을 적용했거나, 초기에 할당된 위치에서 다른 origin으로 탐색된 경우일 수 있습니다. 이런 경우 프레임 요소의 중첩 navigable에서 실제 정책을 노출하는 것은 교차 origin 문서의 동작에 대한 정보를 누출할 수 있습니다.
<!doctype html> <iframe id="frame" allow="fullscreen; xr-spatial-tracking"></iframe> <script> const iframe_element = document.getElementById("frame"); const iframe_policy = iframe_element.permissionsPolicy; // 프레임 문서가 WebXR을 사용할 수 있으면 true if (iframe_policy.allowsFeature('xr-spatial-tracking')) { // VR 컨트롤 표시 } </script>
iframe 요소의 관찰 가능한 정책은 프레임에 실제로 로드된 콘텐츠와 독립적입니다(교차 origin 정보 누출 방지 목적), 심지어 문서 트리에 포함되어 있는지 여부와도 무관합니다.
<!doctype html> <!-- 이 프레임은 src에 명시된 문서가 로드될 때 fullscreen을 사용할 수 없어야 합니다 --> <iframe id="frame" allow="fullscreen https://example.com" src="https://example.net/" ></iframe> <script> const iframe_element = document.getElementById("frame"); const iframe_policy = iframe_element.permissionsPolicy; // src 속성에 명시된 URL이 정책상 fullscreen을 사용할 수 없으므로 false가 됩니다. const is_fullscreen_allowed_in_frame = iframe_policy.allowsFeature('fullscreen'); const new_frame = document.createElement('iframe'); new_frame.allow = 'sync-xhr'; // src 속성이 아직 설정되지 않았더라도, iframe이 sync-xhr을 사용할 수 있으므로 true가 됩니다. const is_sync_xhr_allowed = new_frame.permissionsPolicy.allowsFeature('sync-xhr'); </script>
7.2. permissionsPolicy 객체
[Exposed =Window ]interface {
PermissionsPolicy boolean (
allowsFeature DOMString ,
feature optional DOMString );
origin sequence <DOMString >();
features sequence <DOMString >();
allowedFeatures sequence <DOMString >(
getAllowlistForFeature DOMString ); };
feature partial interface Document { [SameObject ]readonly attribute PermissionsPolicy ; };
permissionsPolicy partial interface HTMLIFrameElement { [SameObject ]readonly attribute PermissionsPolicy ; };
permissionsPolicy
PermissionsPolicy
객체는 연관된 노드를
가지며, 이는 Node
입니다.
연관된 노드는 PermissionsPolicy
객체가 생성될 때 설정됩니다.
PermissionsPolicy
객체는 기본 origin을
가지며, 이는 origin이고, 값은 PermissionsPolicy
객체의 연관된 노드 상태에 따라
결정됩니다:
-
PermissionsPolicy
객체의 연관된 노드가Document
인 경우, 기본 origin은Document
의 origin입니다. -
PermissionsPolicy
객체의 연관된 노드가Element
인 경우, 기본 origin은Element
의 선언된 origin입니다.
각 Document
는
정책 객체를 가지며, 이는 PermissionsPolicy
인스턴스로 연관된 노드가 해당
Document
입니다.
Document
의
permissionsPolicy
IDL 속성은 가져올 때 해당 Document
의
정책
객체를 반환해야 합니다.
iframe
요소는 정책 객체를 가지며, 이는 PermissionsPolicy
인스턴스로 연관된 노드가 해당
요소입니다.
iframe
의
permissionsPolicy
IDL 속성은 가져올 때 해당
iframe
의
정책 객체를
반환해야 합니다.
allowsFeature(feature, origin)
메서드는 다음 단계를 수행해야 합니다:
-
origin이 생략되면, origin을 이
PermissionsPolicy
객체의 기본 origin으로 설정합니다. -
policy를 이
PermissionsPolicy
객체의 연관된 노드에 대한 관찰 가능한 정책으로 설정합니다. -
policy에서 feature가 origin에 대해 허용된다면 true를 반환합니다.
-
그렇지 않으면 false를 반환합니다.
features()
메서드는 다음 단계를 수행해야 합니다:
-
result를 빈 순서 있는 집합으로 설정합니다.
-
각 지원 기능 feature에 대해:
-
feature를 result에 추가합니다.
-
-
result 반환
allowedFeatures()
메서드는 다음 단계를 수행해야 합니다:
-
result를 빈 순서 있는 집합으로 설정합니다.
-
origin을 이
PermissionsPolicy
객체의 기본 origin으로 설정합니다. -
policy를 이
PermissionsPolicy
객체의 연관된 노드에 대한 관찰 가능한 정책으로 설정합니다. -
각 지원 기능 feature에 대해:
-
policy에서 feature가 origin에 대해 허용된다면 feature를 result에 추가합니다.
-
-
result 반환
getAllowlistForFeature(feature)
메서드는 다음 단계를 수행해야 합니다:
-
result를 빈 리스트로 설정합니다.
-
origin을 이
PermissionsPolicy
객체의 기본 origin으로 설정합니다. -
policy를 이
PermissionsPolicy
객체의 연관된 노드에 대한 관찰 가능한 정책으로 설정합니다. -
feature가 policy에서 origin에 대해 허용되지 않으면 result 반환
-
allowlist가 특별 값
*
이면:-
"
*
"를 result에 추가 -
result 반환
-
-
allowlist의 self-origin이 null이 아니면, 그 직렬화를 result에 추가합니다.
-
allowlist의 src-origin이 null이 아니면, 그 직렬화를 result에 추가합니다.
-
그 외에는, allowlist의 expressions의 각 permissions-source-expression item에 대해:
-
item을 result에 추가
-
-
result 반환
어떤 Node의 관찰 가능한 정책은 해당 Node가 나타내는 navigable에 대해 현재 문서에서 볼 수 있는 정책 정보를 포함한 권한 정책입니다.
Document document의 관찰 가능한 정책을 얻으려면 document의 권한 정책을 반환하세요.
Element node의 관찰 가능한 정책을 얻으려면 다음 단계를 따르세요:
-
inherited policy를 빈 순서 있는 맵으로 설정합니다.
-
각 지원 기능 feature에 대해:
-
isInherited를 컨테이너에서 기능에 대한 상속 정책 정의를 feature, node, node의 선언된 origin에 대해 실행한 결과로 설정합니다.
-
inherited policy[feature]를 isInherited로 설정합니다.
-
-
권한 정책의 새로운 인스턴스를 반환하는데, 상속 정책은 inherited policy, 선언된 정책은 구조체로, 선언 및 리포트 구성이 모두 새로운 순서 있는 맵입니다.
Element node의 선언된 origin을 얻으려면 다음 단계를 따릅니다:
-
node의 node document의 sandboxed origin browsing context flag가 설정되어 있으면, 새로운 불투명 origin을 반환합니다.
-
node의
sandbox
속성이 설정되어 있고,allow-same-origin
키워드를 포함하지 않으면, 새로운 불투명 origin을 반환합니다. -
node의
srcdoc
속성이 설정되어 있으면, node의 node document의 origin을 반환합니다. -
node의
src
속성이 설정되어 있으면:-
url을 node의 src 속성을 node의 node document 기준으로 파싱한 결과로 설정합니다.
-
url이 실패가 아니면 url의 origin을 반환합니다.
-
-
node의 node document의 origin을 반환합니다.
선언된 origin 개념은
프레임에 임베딩 페이지가 로드하려는 문서의 origin을 나타내기 위한 것입니다. 즉, 브라우저가 sandbox
나 srcdoc
속성을
지원하지 않는다면, 선언된 origin을 계산할 때 해당 속성들을 고려하지 않아야 합니다.
8. 보고
Permissions 정책 위반 보고서는 Document의 일부 동작이 정책을 위반했음을 나타냅니다. 각 개별 정책 제어 기능의 명세는 해당 정책을 위반한다는 것이 무엇을 의미하는지와, 위반이 언제 발생했다고 판단하는지 정의해야 합니다.
Permissions 정책 위반 보고서는 보고서 타입 "permissions-policy-violation"을 가집니다.
Permissions 정책 위반 보고서는 ReportingObserver
에게
표시됩니다.
[Exposed =Window ]interface :
PermissionsPolicyViolationReportBody ReportBody { [Default ]object ();
toJSON readonly attribute DOMString ;
featureId readonly attribute DOMString ?;
sourceFile readonly attribute long ?;
lineNumber readonly attribute long ?;
columnNumber readonly attribute DOMString ;
disposition readonly attribute DOMString ?;
allowAttribute readonly attribute DOMString ?; };
srcAttribute
Permissions 정책 위반 보고서의 body는 JavaScript에서 PermissionsPolicyViolationReportBody
로
표현되며,
다음 필드를 포함합니다:
-
featureId: 정책 제어 기능 중 위반된 정책을 식별하는 문자열입니다. 이 문자열은 관련 보고서를 그룹화하거나 집계하는 데 사용할 수 있습니다.
-
sourceFile: 알 수 있다면, 위반이 발생한 파일, 아니면 null.
-
lineNumber: 알 수 있다면, sourceFile에서 위반이 발생한 줄 번호, 아니면 null.
-
columnNumber: 알 수 있다면, sourceFile에서 위반이 발생한 열 번호, 아니면 null.
-
disposition: 해당 위반된 정책이 실제로 적용(enforce)되었는지 여부를 나타내는 문자열입니다. disposition 값은 정책이 적용되었다면 "enforce"이고, 위반이 보고서 생성만을 유발하고 사용자 에이전트에서 추가 동작이 없다면 "report"가 됩니다.
-
allowAttribute: 잠재적 위반 보고 중, 특정
iframe
요소로 귀속시킬 수 있다면 해당 요소의allow
속성 값, 그 외엔 생략. -
srcAttribute: 잠재적 위반 보고 중, 특정
iframe
요소로 귀속시킬 수 있다면 해당 요소의src
속성 값, 그 외엔 생략.
8.1. `Permissions-Policy-Report-Only
`
HTTP 헤더 필드
`Permissions-Policy-Report-Only
`
HTTP 헤더 필드는 응답 (서버 → 클라이언트)에서 클라이언트가 해당 정책을 실제로 적용하지 않고, 만약 정책이
활성화되어 있었다면 위반되었을 정책에 대해 보고서를 전송하도록 사용할 수 있습니다.
`Permissions-Policy-Report-Only
`
는 구조화된 헤더입니다. 값은 반드시 딕셔너리여야 합니다.
딕셔너리의 의미론은 § 5.2 구조화된 헤더 직렬화에서 정의됩니다.
처리 단계는 § 9.2 사전과 출처로 정책 구성에서 정의됩니다.
9. 알고리즘
9.1. 응답 정책 처리
-
header name을 report-only가 True면 "
Permissions-Policy-Report-Only
", 아니면 "Permissions-Policy
"로 설정합니다. -
parsed header를 response의 header list에서 header name과 "dictionary"를 사용해 get a structured field value를 실행한 결과로 설정합니다.
-
parsed header가 null이면, 빈 순서 있는 맵을 반환합니다.
-
policy를 parsed header와 origin에 대해 사전과 출처로 정책 구성을 실행한 결과로 설정합니다.
-
policy를 반환합니다.
9.2. 사전과 출처로 정책 구성
-
declarations를 빈 순서 있는 맵으로 설정합니다.
-
reporting-config를 빈 순서 있는 맵으로 설정합니다.
-
각 feature-name → (value, params)에 대해 dictionary에서 반복:
-
feature를 feature-name이 식별하는 정책 제어 기능으로 설정.
-
params["report-to"]가 존재하고 문자열이면, reporting-config[feature]에 params["report-to"]를 설정.
-
allowlist를 새로운 허용 목록으로 설정.
-
value가 토큰
*
이거나, value가*
토큰을 포함하는 리스트면, allowlist를 특별 값*
로 설정. -
그 외의 경우:
-
value가 토큰
self
면, allowlist의 self-origin을 origin으로 설정. -
그 외에 value가 리스트이면, 각 element에 대해 value에서 반복:
-
element가 토큰
self
면, allowlist의 self-origin을 origin으로 설정. -
element가 유효한 permissions-source-expression이면, append element를 allowlist의 expressions에 추가.
-
-
-
declarations[feature]를 allowlist로 설정.
-
«declarations, reporting-config»를 반환.
9.3. 정책 지시문 파싱
-
directive를 빈 순서 있는 맵으로 설정.
-
value를 U+003B (;)로 엄격하게 분할하여 얻은 각 serialized-declaration에 대해:
-
tokens를 serialized-declaration을 ASCII 공백으로 분할한 결과로 설정.
-
tokens가 빈 리스트면, 계속.
-
feature-name을 tokens의 첫 번째 요소로 설정.
-
feature를 feature-name이 식별하는 정책 제어 기능으로 설정.
-
targetlist를 tokens의 나머지 요소(있다면)로 설정.
-
allowlist를 새로운 허용 목록으로 설정.
-
targetlist의 어떤 요소가 문자열 "
*
"이면, allowlist를 특별 값*
로 설정. -
그 외의 경우:
-
targetlist가 비어 있고 target origin이 주어졌다면, allowlist의 src-origin을 target origin으로 설정.
-
targetlist의 각 element에 대해:
-
element가 ASCII 대소문자 구분 없이 "
'self'
"와 일치한다면:-
allowlist의 self-origin을 container origin으로 설정.
-
다음 element로 계속.
-
-
target origin이 주어지고 element가 ASCII 대소문자 구분 없이 "
'src'
"와 일치한다면:-
allowlist의 src-origin을 target origin으로 설정.
-
다음 element로 계속.
-
-
result를 element에 URL parser를 실행한 결과로 설정.
-
result가 실패가 아니면:
-
target를 result의 origin으로 설정.
-
target이 불투명 origin이 아니면, append target의 직렬화를 allowlist의 expressions에 추가.
-
-
-
-
directive[feature]를 allowlist로 설정.
-
-
directive를 반환
9.4. 권한 정책 속성 처리
-
container policy를 정책 지시문 파싱을 element의
allow
속성 값, element의 origin, element의 선언된 origin을 인자로 실행한 결과로 설정합니다. -
element의
allowfullscreen
속성이 지정되어 있고, container policy에fullscreen
기능에 대한 항목이 없으면, -
container policy를 반환합니다.
9.5. 내비게이블에 대한 권한 정책 생성
-
단언: null이 아니면, container는 내비게이블 컨테이너입니다.
-
inherited policy를 새로운 순서 있는 맵으로 설정합니다.
-
-
isInherited를 컨테이너에서 기능에 대한 상속 정책 정의를 feature, container, origin에 대해 실행한 결과로 설정합니다.
-
inherited policy[feature] = isInherited로 설정합니다.
-
-
policy를 새 권한 정책으로, 상속 정책은 inherited policy, 선언된 정책은 «[], []»로 설정합니다.
-
policy를 반환합니다.
9.6. 응답에서 내비게이블에 대한 권한 정책 생성
-
policy를 내비게이블에 대한 권한 정책 생성을 container, origin에 대해 실행한 결과로 설정합니다.
-
d를 응답 정책 처리를 response, origin, report-only에 대해 실행한 결과로 설정합니다.
-
각 feature → allowlist에 대해 d의 선언에서 반복:
-
policy를 반환합니다.
9.7. 컨테이너에서 기능에 대한 상속 정책 정의
Document
의
origin (origin), 옵션 boolean
(report-only), 기본 False를 받아, 상속 정책 값을
반환합니다.
-
container가 null이면, "
Enabled
"를 반환합니다. -
기능 값 가져오기를 feature, container의 node document, container의 node document의 origin, report-only로 실행한 결과가 "
Disabled
"이면, "Disabled
"를 반환합니다. -
기능 값 가져오기를 feature, container의 node document, origin, report-only로 실행한 결과가 "
Disabled
"이면, "Disabled
"를 반환합니다. -
container policy를 권한 정책 속성 처리를 container에 대해 실행한 결과로 설정합니다.
-
feature가 container policy에 존재하면:
-
feature의 기본 허용 목록이
*
이면, "Enabled
"를 반환합니다. -
feature의 기본 허용 목록이
'self'
이고, origin이 container의 node document의 origin과 동일 origin이면 "Enabled
"를 반환합니다. -
그 밖의 경우 "
Disabled
"를 반환합니다.
9.8. 기능 값 가져오기
9.9. 권한 정책 확인
Disabled
", 그렇지 않으면
"Enabled
"를 반환합니다.
9.10. 문서에서 특정 출처에 기능이 활성화되어 있는가?
Document
객체
(document), origin (origin), 옵션 boolean
(report), 기본 True를 받아, feature가 비활성화되어야 하면 "Disabled
", 그렇지 않으면
"Enabled
"를 반환합니다. report가 True이면, document의 권한 정책 또는 보고 전용 권한 정책에서 기능이 활성화되어 있지 않으면 보고를 생성 및 큐잉합니다.
참고: report의 기본값 True는 대부분의 권한 정책 확인이 기능이 활성화되어 있지 않으면 위반 보고서를 생성하는 결과가 됨을 의미합니다. 이는 실제로 기능 사용 시도에 대한 검사에서는 기대되는 동작입니다. 단순히 기능의 상태만 질의하는 경우(실제 사용 시도가 아님)는 report를 False로 설정해야 합니다.
-
policy를 document의 권한 정책으로 설정합니다.
-
report-only policy를 document의 보고 전용 권한 정책으로 설정합니다.
-
result를 권한 정책 확인을 policy, feature, origin, document의 origin에 대해 실행한 결과로 설정합니다.
-
report-only result를 권한 정책 확인을 report-only policy, feature, origin, document의 origin에 대해 실행한 결과로 설정합니다.
-
report가 True이면:
-
settings를 document의 환경 설정 객체로 설정합니다.
-
result가 "
Disabled
"이면:-
endpoint를 기능에 대한 보고 엔드포인트 얻기를 feature, policy에 대해 실행한 결과로 설정합니다.
-
권한 정책 위반 보고서 생성을 feature, settings, "
Enforce
", endpoint에 대해 호출합니다.
-
-
그 외 report-only result가 "
Disabled
"이면:-
report-only endpoint를 기능에 대한 보고 엔드포인트 얻기를 feature, report-only policy에 대해 실행한 결과로 설정합니다.
-
권한 정책 위반 보고서 생성을 feature, settings, "
Report
", report-only endpoint에 대해 호출합니다.
-
-
-
result를 반환합니다
9.11. 기능에 대한 보고 엔드포인트 얻기
9.12. 컨테이너 내 권한 정책 잠재적 위반 확인
-
document를 container의 node document로 설정합니다.
-
settings를 document의 환경 설정 객체로 설정합니다.
-
-
컨테이너에서 기능에 대한 상속 정책 정의를 feature, container, container의 선언된 origin에 대해 실행한 결과가 "
Disabled
"이면:-
endpoint를 기능에 대한 보고 엔드포인트 얻기를 feature, document의 권한 정책에 대해 실행한 결과로 설정합니다.
-
권한 정책 잠재적 위반 보고서 생성을 feature, settings, "
Enforce
", endpoint, allowAttribute, srcAttribute에 대해 호출합니다.
-
-
그 외 컨테이너에서 기능에 대한 상속 정책 정의를 feature, container, container의 선언된 origin, True에 대해 실행한 결과가 "
Disabled
"이면:-
report-only endpoint를 기능에 대한 보고 엔드포인트 얻기를 feature, document의 보고 전용 권한 정책에 대해 실행한 결과로 설정합니다.
-
권한 정책 잠재적 위반 보고서 생성을 feature, settings, "
Report
", report-only endpoint, allowAttribute, srcAttribute에 대해 호출합니다.
-
-
9.13. 권한 정책 위반 보고서 생성
-
body를 새로운
PermissionsPolicyViolationReportBody
로 생성하고, 아래와 같이 초기화:- featureId
-
feature의 문자열 표현.
- sourceFile
-
null
- lineNumber
-
null
- columnNumber
-
null
- disposition
-
disposition
-
사용자 에이전트가 현재 스크립트를 실행 중이며 settings에서 source file의 URL, line number, column number를 추출할 수 있으면, body의 sourceFile, lineNumber, columnNumber를 해당 값으로 설정합니다.
-
generate and queue a report를 body, "permissions-policy-violation", endpoint, settings에 대해 실행합니다.
9.14. 권한 정책 잠재적 위반 보고서 생성
-
body를 새로운
PermissionsPolicyViolationReportBody
로 생성하고, 아래와 같이 초기화:- featureId
-
feature의 문자열 표현.
- sourceFile
-
null
- lineNumber
-
null
- columnNumber
-
null
- disposition
-
disposition
- allowAttribute
-
allowAttribute
- srcAttribute
-
srcAttribute
-
사용자 에이전트가 현재 스크립트를 실행 중이며 settings에서 source file의 URL, line number, column number를 추출할 수 있으면, body의 sourceFile, lineNumber, columnNumber를 해당 값으로 설정합니다.
-
generate and queue a report를 body, "potential-permissions-policy-violation", endpoint, settings에 대해 실행합니다.
9.15. 요청이 기능을 사용할 수 있도록 허용해야 하는가?
true
를, 그렇지 않으면 false
를
반환합니다.
-
client를 request의 client로 설정합니다.
-
client가 null이면,
false
를 반환합니다. -
client의 global object가
Window
가 아니면,false
를 반환합니다.Window가 아닌 컨텍스트(예:WorkerGlobalScope
또는WorkletGlobalScope
) 내 Permissions Policy 지원은 이슈 #207에서 논의 중입니다. 해당 이슈가 해결되면 이 알고리즘을 업데이트하여 이러한 컨텍스트에서 시작된 fetch가 정책 제어 기능을 사용할 수 있도록 하세요. 해결 전까지는 이러한 컨텍스트에서는 모든 정책 제어 기능(예: Client Hints를 서드파티에 전송 등)을 허용하지 않습니다. -
document를 client의 global object의 관련
Document
로 설정합니다. -
origin을 request의 origin으로 설정합니다.
-
result를 문서에서 특정 출처에 기능이 활성화되어 있는가?를 feature, document, origin에 대해 실행한 결과로 설정합니다.
-
result가 "
Enabled
"이면,true
를 반환합니다. -
그 밖의 경우
false
를 반환합니다.
10. 다른 명세 변경사항
10.1. HTML 명세 변경사항
모든Document
는
보고 전용 권한 정책을 가지며, 이는 권한 정책이고, 처음에는 비어 있습니다.
7.5.1 Shared document creation infrastructure에서, 3단계 이후 다음 단계를 추가하세요:
-
reportOnlyPermissionsPolicy를 응답에서 내비게이블에 대한 권한 정책 생성을 navigationParams의 navigable의 container, navigationParams의 origin, navigationParams의 response, True에 대해 실행한 결과로 설정하세요.
그리고 같은 섹션의 10단계에서, 새 Document
의
보고 전용 권한 정책을
reportOnlyPermissionsPolicy로 설정하세요.
iframe load event steps에서, 6단계 이후 다음 단계를 추가하세요:
-
컨테이너 내 권한 정책 잠재적 위반 확인을 element, element의 allow 속성, element의 src 속성에 대해 실행하세요.
11. IANA 고찰
영구 메시지 헤더 필드 레지스트리는 다음 등록사항으로 갱신되어야 합니다 [RFC3864]:
- 헤더 필드 이름
- Permissions-Policy
- 적용 프로토콜
- http
- 상태
- standard
- 작성자/변경 관리자
- W3C
- 명세 문서
- https://www.w3.org/TR/permissions-policy/
12. 프라이버시 및 보안
이 명세는 임베딩 페이지가 임베딩된 페이지에 적용할 정책을 표준화합니다. iframe의
sandbox
와
유사하게, 이는 임베딩된 페이지의 명시적 허가 없이도 실행될 수 있으므로, 기존 기능의 동작이 적절한 컨테이너 정책으로 다른 문서에 임베딩함으로써 게시된 웹사이트에서 변경될 수 있습니다.
따라서 가장 큰 프라이버시 및 보안 우려는 다음과 같습니다:
- 교차 출처 하위 프레임의 동작이 임베더에게 노출됨
- 임베더가 제어하는 하위 프레임에서 예상치 못한 동작 변화 발생
어느 정도 이러한 우려는 이미 웹 플랫폼에 존재하며, 이 명세는 최소한 불필요하게 악화시키지 않도록 시도합니다.
개별 기능의 설계에 따라 보안 및 프라이버시 문제도 발생할 수 있으므로, 이 명세와 통합할 때 주의가 필요합니다. 이 섹션은 이러한 이슈를 유발할 수 있는 동작의 유형에 대한 안내를 제공합니다.
12.1. 교차 출처 동작 노출
기능은 프레임된 문서에서 정책이 위반되더라도, 다른 프레임의 문서에서는 관찰할 수 없도록 설계되어야 합니다. 예를 들어, 임베딩 문서에서 특정 기능이 정책에 의해 비활성화된 상태에서 사용될 경우 이벤트가 발생하는 가상의 기능이 있다면, 임베더는 해당 기능의 상태에 대한 정보를 추출할 수 있습니다. 예를 들어, 해당 기능이 사이트에 로그인한 사용자만 사용할 수 있다면, 임베더는 프레임에 대해 해당 기능을 비활성화하고, 발생하는 이벤트를 감지하여 사용자의 로그인 여부를 확인할 수 있습니다.
내성 API는 임베딩 문서가 이미 유추할 수 있는 하위 프레임의 정책 정보만 보여주도록 설계되었습니다.
이 관찰 가능한 정책은 프레임
문서에 전달된 HTTP 헤더에 영향을 받지 않으며, 프레임이 자체적으로 탐색해도 변경되지 않습니다. 다른 origin으로 탐색되어 다른 정책이 적용되는 경우에도 마찬가지입니다.
<iframe>
요소의 src
속성을 설정하여 발생한 탐색만 관찰 가능한 정책을 갱신시킵니다.
12.2. 예상치 못한 동작 변화
Permissions Policy 메커니즘은 문서가 하위 프레임이 로드될 때 어떤 기능을 사용할 수 있고 없을지 제어할 수 있게 합니다. 기존 웹 플랫폼의 오랜 동작을 나타내는 기능의 경우, 기존에 게시된 콘텐츠는 특정 API가 실패할 수 있다는 점을 예상하지 않고 작성되었을 수 있습니다.
실질적(하지만 인위적인) 예시로, 동기 XMLHttpRequest를 사용하여 사용자가 페이지에 접근할 권한이 충분한지 확인하는 문서를 고려해보세요:
<!DOCTYPE html> <h1>Welcome to SecureCorp!</h1> <script> var req = new XMLHttpRequest(); req.open("GET", "/api/security_check.json", false); req.send(); if (req.response == "untrusted user") { // User is not logged in; redirect to a safe page location.href = "/security_check_failed.html"; } </script> <!-- Page continues with assumption that user is logged in -->
만약 이 문서가 "sync-xhr
" 기능을 비활성화한 페이지에 임베딩된다면, XMLHttpRequest.open()
호출이 실패하여
보안 검사가 무시될 수 있습니다.
이러한 동작 강제는 이미 웹에서 가능함을 유념하세요: 일부 기능은 최상위 문서에서만 허용되고 iframe에서는 허용되지 않으며, iframe 샌드박싱을 통해 기능 접근이 불가한 프레임을 임베딩하는 것도 유사하게 활용할 수 있습니다.
일반적으로 이러한 우려는 두 가지 방식으로 완화됩니다:
- 취약한 페이지는
X-Frame-Options
HTTP 헤더를 통해 공격자가 프레이밍하지 못하도록 할 수 있습니다. - 사이트는 API나 동작을 사용하기 전에 기능 감지를 활용하고, 문서화된 오류나 예외를 적절히 처리해야 합니다.
- 기능 감지가 불가능한 경우, 새로운 웹 콘텐츠는
policy
객체를 사용하여 현재 적용된 권한 정책을 검사하고, 이에 따라 동작이나 UI를 조정할 수 있습니다.
Permissions Policy와 통합하는 기능의 작성자는 문서가 기능이 비활성화된 상태에서 사용을 시도할 때 언제, 어떻게 실패할지 결정할 수 있습니다. 기존 실패 동작이 있다면 이를 활용하여 기존 콘텐츠가 해당 실패를 이미 잘 처리하도록 유도해야 합니다.
12.3. 임베딩 정책 노출
페이지가 임베딩하는 교차 출처 페이지의 동작에 대해 추론할 수 있는 정보는 제한하도록 주의가 기울여졌습니다. 하지만 어떤 시나리오에서는, 임베딩된 페이지가 자신에게 적용된 정책을 검사함으로써 임베더에 대한 정보를 추론할 수도 있습니다.
이는 기존 document.fullscreenEnabled
속성과 유사하며, 임베딩된 문서가 임베더가 Fullscreen API 사용 권한을 부여했는지 유추할 수
있습니다. 예를 들어, 해당 권한이 특정 조건(사용자가 임베딩 사이트에 로그인한 경우)에만 부여된다면, 임베딩된 사이트는 임베더의 상태에 대해 일부 정보를 알게 될 수 있습니다.
13. 변경 로그
13.1. FPWD 이후 변경사항
-
문서 생성 이전에 Feature Policy를 생성하는 새 알고리즘을 노출. 링크
-
더 이상 필요하지 않은 알고리즘 제거. 링크
-
same-origin-domain 검사에서 same-origin 검사로 변경. 링크
-
헤더와 속성 결합 방식 OR에서 AND 의미론으로 변경. 링크
-
"Permissions Policy"로 이름 변경. 링크
-
"Permissions-Policy"를 구조화된 헤더로 정의. 링크
-
편집상의 수정.
-
allowpaymentrequest
속성이 Payment Request API 및 HTML에서 폐지됨에 따라 제거됨. 링크