기능 정책 소개

요약

기능 정책을 사용하면 웹 개발자가 브라우저에서 특정 API 및 웹 기능의 동작을 선택적으로 사용 설정, 사용 중지, 수정할 수 있습니다. CSP와 비슷하지만 보안을 제어하는 대신 기능을 제어합니다.

기능 정책 자체는 개발자와 브라우저 간의 사전 동의가 거의 없으므로 고품질 웹 앱을 빌드하고 유지한다는 Google의 목표를 촉진하는 데 도움이 됩니다.

소개

웹용으로 빌드하는 것은 어려운 여정입니다. 성능이 우수하고 최신 권장사항을 모두 사용하는 우수한 웹 앱을 빌드하는 것만으로도 충분히 어렵습니다. 시간이 지나도 훌륭한 환경을 유지하기는 더욱 어렵습니다. 프로젝트가 발전함에 따라 개발자들이 참여하고, 새로운 기능이 도입되고, 코드베이스가 커집니다. 한 번 달성한 Great Experience TM의 경우 성능이 저하되고 UX가 악화되기 시작할 수 있습니다. 기능 정책은 크리에이터가 올바른 방향으로 나아갈 수 있도록 설계되었습니다.

기능 정책을 사용하면 브라우저에서 사이트 전반에서 사용되는 특정 기능에 적용할 일련의 '정책'을 선택할 수 있습니다. 이러한 정책은 사이트에서 액세스할 수 있는 API 또는 특정 기능에 대한 브라우저의 기본 동작을 수정할 수 있는 API를 제한합니다.

다음은 기능 정책으로 할 수 있는 작업의 예입니다.

  • 모바일 및 서드 파티 동영상에서 autoplay기본 동작을 변경합니다.
  • 사이트가 camera 또는 microphone와 같은 민감한 API를 사용하지 못하도록 제한합니다.
  • iframe이 fullscreen API를 사용하도록 허용합니다.
  • 동기식 XHR 및 document.write()와 같은 오래된 API의 사용을 차단합니다.
  • 이미지 크기가 적절하고(예: 레이아웃 트래싱 방지) 표시 영역보다 너무 크지 않도록 합니다(예: 사용자의 대역폭 낭비).

정책은 개발자와 브라우저 간의 계약입니다. 이러한 파일은 개발자의 의도가 무엇인지 브라우저에 알려주므로 앱이 레일에서 벗어나 잘못된 작업을 수행하려고 할 때 정직함을 유지하는 데 도움이 됩니다. 사이트 또는 삽입된 서드 파티 콘텐츠가 개발자가 미리 선택한 규칙을 위반하려고 하면 브라우저가 더 나은 UX로 동작을 재정의하거나 API를 완전히 차단합니다.

기능 정책 사용

기능 정책은 다음과 같은 두 가지 방법으로 기능을 제어합니다.

  1. Feature-Policy HTTP 헤더를 통해
  2. iframe에서 allow 속성을 사용합니다.

기능 정책을 사용하는 가장 쉬운 방법은 페이지의 응답과 함께 Feature-Policy HTTP 헤더를 전송하는 것입니다. 이 헤더의 값은 브라우저가 특정 출처에 대해 준수할 정책 또는 정책 집합입니다.

Feature-Policy: <feature> <allow list origin(s)>

원본 허용 목록은 다음과 같은 여러 값을 사용할 수 있습니다.

  • *: 이 기능은 최상위 탐색 컨텍스트와 중첩된 탐색 컨텍스트(iframe)에서 허용됩니다.
  • 'self': 이 기능은 최상위 탐색 컨텍스트 및 동일 출처 중첩 브라우징 컨텍스트에서 허용됩니다. 중첩된 탐색 컨텍스트의 교차 출처 문서에서는 허용되지 않습니다.
  • 'none': 이 기능은 최상위 탐색 컨텍스트에서 허용되지 않으며 중첩된 탐색 컨텍스트에서 허용되지 않습니다.
  • <origin(s)>: 정책을 사용 설정할 특정 출처입니다 (예: https://example.com).

사이트에서 Geolocation API를 사용하는 모든 콘텐츠를 차단하려고 한다고 가정해 보겠습니다. 이렇게 하려면 geolocation 기능에 'none'의 엄격한 허용 목록을 전송하면 됩니다.

Feature-Policy: geolocation 'none'

코드나 iframe이 Geolocation API를 사용하려고 하면 브라우저에서 차단합니다. 이러한 경우는 사용자가 이전에 위치 공유 권한을 부여한 경우에도 마찬가지입니다.

설정된 위치정보 정책 위반
설정된 위치정보 정책을 위반합니다.

경우에 따라서는 이 정책을 약간 완화하는 것이 좋습니다. 허용 목록에 'self'를 설정하여 자체 출처에서 Geolocation API를 사용하도록 허용하지만 서드 파티 콘텐츠가 이에 액세스하지 못하도록 할 수 있습니다.

Feature-Policy: geolocation 'self'

iframe allow 속성

기능 정책을 사용하는 두 번째 방법은 iframe 내에서 콘텐츠를 제어하는 것입니다. allow 속성을 사용하여 삽입된 콘텐츠의 정책 목록을 지정합니다.

<!-- Allow all browsing contexts within this iframe to use fullscreen. -->
<iframe src="https://example.com..." allow="fullscreen"></iframe>

<!-- Equivalent to: -->
<iframe src="https://example.com..." allow="fullscreen *"></iframe>

<!-- Allow only iframe content on a particular origin to access the user's location. -->
<iframe
  src="https://another-example.com/demos/..."
  allow="geolocation https://another-example.com"
></iframe>

기존 iframe 속성은 어떻게 되나요?

기능 정책에서 제어하는 기능 중에는 동작을 제어하는 기존 속성이 있는 기능이 있습니다. 예를 들어 <iframe allowfullscreen>는 iframe 콘텐츠가 HTMLElement.requestFullscreen() API를 사용하도록 허용하는 속성입니다. Payment Request APIgetUserMedia()를 각각 허용하는 allowpaymentrequestallowusermedia 속성도 있습니다.

가능하면 이러한 이전 속성 대신 allow 속성을 사용하세요. allow 속성을 상응하는 기존 속성과 함께 사용하여 이전 버전과의 호환성을 지원해야 하는 경우에는 완벽하게 괜찮습니다 (예: <iframe allowfullscreen allow="fullscreen">). 단, 더 제한적인 정책이 적용됩니다. 예를 들어 allow="fullscreen 'none'"allowfullscreen보다 제한적일 때 다음 iframe은 전체 화면으로 전환할 수 없습니다.

<!-- Blocks fullscreen access if the browser supports feature policy. -->
<iframe allowfullscreen allow="fullscreen 'none'" src="..."></iframe>

한 번에 여러 정책 관리

;으로 구분된 정책 지시문 목록과 함께 HTTP 헤더를 전송하여 여러 기능을 동시에 제어할 수 있습니다.

Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;

또는 정책마다 별도의 헤더를 전송합니다.

Feature-Policy: unsized-media 'none'
Feature-Policy: geolocation 'self' https://example.com
Feature-Policy: camera *;

이 예에서는 다음을 실행합니다.

  • 모든 탐색 컨텍스트에서 unsized-media 사용을 금지합니다.
  • 페이지 자체 출처 및 https://example.com를 제외한 모든 탐색 컨텍스트에 geolocation를 사용하지 못하도록 합니다.
  • 모든 탐색 컨텍스트에 camera 액세스를 허용합니다.

- iframe에 여러 정책 설정

<!-- Blocks the iframe from using the camera and microphone
     (if the browser supports feature policy). -->
<iframe allow="camera 'none'; microphone 'none'"></iframe>

JavaScript API

Chrome 60에서는 Feature-Policy HTTP 헤더와 iframe의 allow 속성에 대한 지원을 추가했지만 JavaScript API는 Chrome 74에서 추가되었습니다.

이 API를 사용하면 클라이언트 측 코드가 페이지, 프레임 또는 브라우저에서 허용되는 기능을 결정할 수 있습니다. 기본 문서의 경우 document.featurePolicy, iframe의 경우 frame.featurePolicy에서 혜택에 액세스할 수 있습니다.

아래 예는 사이트 https://example.comFeature-Policy: geolocation 'self' 정책을 전송한 결과를 보여줍니다.

/* @return {Array<string>} List of feature policies allowed by the page. */
document.featurePolicy.allowedFeatures();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {boolean} True if the page allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature('geolocation');
// → true

/* @return {boolean} True if the provided origin allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature(
  'geolocation',
  'https://another-example.com/'
);
// → false

/* @return {Array<string>} List of feature policies allowed by the browser
regardless of whether they are in force. */
document.featurePolicy.features();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {Array<string>} List of origins (used throughout the page) that are
   allowed to use the 'geolocation' feature. */
document.featurePolicy.getAllowlistForFeature('geolocation');
// → ["https://example.com"]

정책 목록

그러면 기능 정책을 통해 제어할 수 있는 기능은 무엇인가요?

현재 구현된 정책과 사용 방법에 관한 문서가 부족합니다. 또한 여러 브라우저에서 사양을 채택하고 다양한 정책을 구현함에 따라 목록은 시간이 지남에 따라 늘어납니다. 기능 정책은 계속 변경되므로 유용한 참조 문서가 필요합니다.

현재 제어 가능한 기능을 확인하는 방법에는 몇 가지가 있습니다.

  • 데모의 기능 정책 키친 싱크를 확인하세요. Blink에서 구현된 각 정책의 예가 나와 있습니다.
  • Chrome 소스에서 기능 이름 목록을 확인하세요.
  • about:blank에서 document.featurePolicy.allowedFeatures()를 쿼리하여 목록을 찾습니다.
        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • Blink에서 구현되었거나 고려 중인 정책은 chromestatus.com에서 확인하세요.

이러한 정책 중 일부를 사용하는 방법을 확인하려면 사양의 GitHub 저장소를 확인하세요. 일부 정책에 대한 설명이 포함되어 있습니다.

FAQ

기능 정책은 언제 사용해야 하나요?

모든 정책은 선택사항이므로 적절한 때/장소에 기능 정책을 사용하세요. 예를 들어 앱이 이미지 갤러리인 경우 maximum-downscaling-image 정책을 사용하면 거대한 이미지를 모바일 뷰포트로 전송하지 않을 수 있습니다.

document-writesync-xhr과 같은 다른 정책은 더 신중하게 사용해야 합니다. 이를 사용 설정하면 광고와 같은 서드 파티 콘텐츠가 손상될 수 있습니다. 반면 기능 정책은 페이지에서 이러한 최악의 API를 절대 사용하지 않도록 할 수 있습니다.

개발 또는 프로덕션 단계에서 기능 정책을 사용하나요?

둘 다입니다. 개발 중에는 정책을 사용 설정하고 프로덕션 중에는 정책을 활성 상태로 유지하는 것이 좋습니다. 개발 중에 정책을 사용 설정하면 처음부터 올바르게 시작하는 데 도움이 될 수 있습니다. 이를 통해 예기치 않은 회귀가 발생하기 전에 이를 포착할 수 있습니다. 프로덕션에서 정책을 사용 설정하여 사용자에게 특정 UX를 보장합니다.

서버에 정책 위반을 신고할 방법이 있나요?

Reporting API개발 중입니다. 사이트에서 CSP 위반 또는 지원 중단에 대한 보고서를 수신하도록 선택할 수 있는 것과 마찬가지로 기능 정책 위반에 관한 보고서를 현장에서 받을 수 있습니다.

iframe 콘텐츠의 상속 규칙은 무엇인가요?

스크립트 (퍼스트 파티 또는 서드 파티)는 탐색 컨텍스트의 정책을 상속합니다. 즉, 최상위 스크립트는 기본 문서의 정책을 상속합니다.

iframe는 상위 페이지의 정책을 상속합니다. iframeallow 속성이 있는 경우 상위 페이지와 allow 목록 중 더 엄격한 정책이 우선 적용됩니다. iframe 사용에 관한 자세한 내용은 iframe의 allow 속성을 참고하세요.

아니요. 정책의 전체 기간은 단일 페이지 탐색 응답에 적용됩니다. 사용자가 새 페이지로 이동하면 정책이 적용되려면 새 응답에서 Feature-Policy 헤더를 명시적으로 전송해야 합니다.

어떤 브라우저가 기능 정책을 지원하나요?

브라우저 지원에 관한 최신 세부정보는 caniuse.com을 참고하세요.

현재 Chrome은 기능 정책을 지원하는 유일한 브라우저입니다. 그러나 전체 API 노출 영역이 선택되거나 기능을 감지할 수 있으므로 기능 정책은 점진적 개선에 적합합니다.

결론

기능 정책을 사용하면 더 나은 UX와 우수한 실적을 달성하는 데 도움이 됩니다. 이는 특히 앱을 개발하거나 유지관리할 때 유용합니다. 잠재적인 실수가 코드베이스에 침투하기 전에 이를 방지할 수 있기 때문입니다.

추가 리소스: