기능 정책 소개

요약

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

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

소개

웹용으로 개발하기란 어려운 일입니다. 성능을 향상하고 모든 최신 권장사항을 사용하는 최고의 웹 앱을 빌드하기는 매우 어렵습니다. 시간이 지나도 훌륭한 환경을 유지하기는 더욱 어렵습니다. 프로젝트가 발전함에 따라 개발자들이 참여하고, 새로운 기능이 도입되고, 코드베이스가 커집니다. 한 번 달성한 훌륭한 경험 TM은 악화되기 시작할 수 있고 UX가 악화되기 시작할 수 있습니다. 기능 정책은 사용자가 정책을 준수할 수 있도록 설계되었습니다.

기능 정책을 사용하면 사이트 전체에서 사용되는 특정 기능을 브라우저에서 시행할 '정책' 집합을 선택할 수 있습니다. 이러한 정책은 사이트에서 액세스하거나 특정 기능에 대한 브라우저의 기본 동작을 수정할 수 있는 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를 사용하려고 하면 브라우저에서 이를 차단합니다. 사용자가 이전에 위치 공유 권한을 부여한 경우에도 마찬가지입니다.

위치정보 설정 정책 위반
설정된 위치정보 정책 위반

경우에 따라서는 이 정책을 약간 완화하는 것이 좋습니다. Google은 자체 출처에서 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()를 각각 허용하는 allowpaymentrequest 속성과 allowusermedia 속성도 있습니다.

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

<!-- 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에서는 iframe에서 Feature-Policy HTTP 헤더 및 allow 속성 지원을 추가했지만 Chrome 74에서는 JavaScript API가 추가되었습니다.

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

예시

아래 예는 https://example.com 사이트에서 Feature-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",
        ...
  • chromestatus.com에서 Blink에서 구현되었거나 검토 중인 정책을 확인합니다.

이러한 정책 중 일부를 사용하는 방법을 확인하려면 사양의 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와 우수한 성능을 향한 충분한 조명을 제공하는 데 도움이 될 수 있습니다. 특히 앱을 개발하거나 유지관리할 때 유용합니다. 코드베이스에 몰래 침투하기 전에 발생할 수 있는 잠재적 공격을 방지하는 데 도움이 되기 때문입니다.

추가 리소스: