콘텐츠 보안 정책 (CSP)

콘텐츠 보안 정책Content Security Policy (CSP)을 설정하는 것은 어떤 정책을 실행하게 할 것인지를 결정하는 것을 포함하고 이런 정책 실행 부분을 Content-Security-Policy 헤더를 사용해서 정책을 실행하게 설정하는 것입니다.

CSP는 이전 버전과 호환되도록 설계되었습니다 (이전 버전과의 호환이 되지 않음을 명시한 CSP 버전 2는 제외됩니다; 여기에서 1.1 섹션의 자세한 내용을 볼 수 있습니다). Browsers that don't support it still work with servers that implement it, and vice-versa: browsers that don't support CSP simply ignore it, functioning as usual, defaulting to the standard same-origin policy for web content. If the site doesn't offer the CSP header, browsers likewise use the standard same-origin policy.

To enable CSP, you need to configure your web server to return the Content-Security-Policy HTTP header (sometimes you will see mentions of the X-Content-Security-Policy header, but that's an older version and you don't need to specify it anymore).

Alternatively, the <meta> element can be used to configure a policy, for example: <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

위험 요소

사이트 간 스크립팅 완화

A primary goal of CSP is to mitigate and report XSS attacks. XSS attacks exploit the browser's trust of the content received from the server. Malicious scripts are executed by the victim's browser because the browser trusts the source of the content, even when it's not coming from where it seems to be coming from.

CSP makes it possible for server administrators to reduce or eliminate the vectors by which XSS can occur by specifying the domains that the browser should consider to be valid sources of executable scripts. A CSP compatible browser will then only execute scripts loaded in source files received from those whitelisted domains, ignoring all other script (including inline scripts and event-handling HTML attributes).

As an ultimate form of protection, sites that want to never allow scripts to be executed can opt to globally disallow script execution.

패킷 분석 공격 완화

In addition to restricting the domains from which content can be loaded, the server can specify which protocols are allowed to be used; for example (and ideally, from a security standpoint), a server can specify that all content must be loaded using HTTPS. A complete data transmission security strategy includes not only enforcing HTTPS for data transfer, but also marking all cookies with the secure flag and providing automatic redirects from HTTP pages to their HTTPS counterparts. Sites may also use the Strict-Transport-Security HTTP header to ensure that browsers connect to them only over an encrypted channel.

CSP 사용하기

Configuring Content Security Policy involves adding the Content-Security-Policy HTTP header to a web page and giving it values to control resources the user agent is allowed to load for that page. For example, a page that uploads and displays images could allow images from anywhere, but restrict a form action to a specific endpoint. A properly designed Content Security Policy helps protect a page against a cross site scripting attack. This article explains how to construct such headers properly, and provides examples.

정책 지정

You can use the Content-Security-Policy HTTP header to specify your policy, like this:

Content-Security-Policy: policy

The policy is a string containing the policy directives describing your Content Security Policy.

정책 작성

A policy is described using a series of policy directives, each of which describes the policy for a certain resource type or policy area. Your policy should include a default-src policy directive, which is a fallback for other resource types when they don't have policies of their own (for a complete list, see the description of the default-src directive). A policy needs to include a default-src or script-src directive to prevent inline scripts from running, as well as blocking the use of eval(). A policy needs to include a default-src or style-src directive to restrict inline styles from being applied from a <style> element or a style attribute.

일반적인 사용 예시

웹 사이트를 위한 보안 정책을 사용하기 위해서 공통적인 시나리오들이 있습니다. 여기서 몇몇 예를 살펴보겠습니다.

예제 1

웹사이트의 관리자가 모든 웹 사이트 내의 콘텐츠는 사이트와 같은 도메인에서 제공하게하려고 한다. 단, 서브도메인은 제외:

Content-Security-Policy: default-src 'self'

예제 2

웹 사이트 관리자가 모든 콘텐츠에 대해 신뢰하는 도메인과 그 서브 도메인에게 허용하려 한다.

Content-Security-Policy: default-src 'self' *.mydomain.com

예제 3

웹 사이트 관리자가 웹 애플리케이션의 사용자가 어느 도메인에서라도 이미지를 웹 콘텐츠에 포함하기를 원하지만 오디오나 비디오는 신뢰하는 도메인만으로 제한하고 모든 스크립트는 신뢰할 수 있는 코드를 호스팅하는 특정 서버만 포함 시키려 한다.

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

이것은 기본적으로 콘텐츠는 문서가 있는 원래 호스트에서만 허용된다. 아래와 같은 예외를 포함하고 있다.:

  • 이미지들은 어디서나 다운로드 될 수 있다. ( img-src에 "*" 로 표시).
  • 미디어는 media1.com 와 media2.com 에서만 허용한다 ( 그리고 이들 호스트의 서브도메인은 제외한다).
  • 실행 가능한 스크립트는 오로지 userscripts.example.com에서만 허용한다.

예제 4

온라인 뱅킹 사이트의 관리자가 사용자의 사이트 접속시 공격자가 내용을 엳듣는 것을 방지하기 위해서, 사이트의 모든 콘텐츠가 SSL을 사용해서 전달되도록 하기를 원한다면 다음과 같습니다.

Content-Security-Policy: default-src https://onlinebanking.jumbobank.com

기본 콘텐츠가 전달되는 곳은 지정된 onlinebanking.jumbobank.com 가 HTTPS를 통해서만 사용하도록 정하고 있다.

예제 5

웹 메일 사이트의 관리자가 이메일 안의 HTML을 사용하게 하려하고 이미지는 어느 서버에서나 적재할 수 있지만 Javascript 혹은 다른 잠재적이고 위험한 콘텐츠가 아닌 곳에서는 허용하지 않는다.

Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *

이 예제는 CSP에 script-src;를 이용하지 않았지만 이 사이트는 default-src 디렉티브에 명시되어 설정된다. 이 의미는 스크립트들은 콘텐츠가 적재된 원래 서버에서만 적재될 수 있다는 의미이다.

정책 테스트

To ease deployment, CSP can be deployed in report-only mode. The policy is not enforced, but any violations are reported to a provided URI. Additionally, a report-only header can be used to test a future revision to a policy without actually deploying it.

You can use the Content-Security-Policy-Report-Only HTTP header to specify your policy, like this:

Content-Security-Policy-Report-Only: policy 

If both a Content-Security-Policy-Report-Only header and a Content-Security-Policy header are present in the same response, both policies are honored. The policy specified in Content-Security-Policy headers is enforced while the Content-Security-Policy-Report-Only policy generates reports but is not enforced.

위반사항 보고하기

By default, violation reports aren't sent. To enable violation reporting, you need to specify the report-uri policy directive, providing at least one URI to which to deliver the reports:

Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi

Then you need to set up your server to receive the reports; it can store or process them in whatever manner you feel is appropriate.

위반 보고 구문

The report JSON object contains the following data:

blocked-uri
The URI of the resource that was blocked from loading by the Content Security Policy. If the blocked URI is from a different origin than the document-uri, then the blocked URI is truncated to contain just the scheme, host, and port.
disposition
Either "enforce" or "reporting" depending on whether the Content-Security-Policy-Report-Only header or the Content-Security-Policy header is used.
document-uri
The URI of the document in which the violation occurred.
effective-directive
The directive whose enforcement caused the violation.
original-policy
The original policy as specified by the Content-Security-Policy HTTP header.
referrer
The referrer of the document in which the violation occurred.
script-sample
The first 40 characters of the inline script, event handler, or style that caused the violation.
status-code
The HTTP status code of the resource on which the global object was instantiated.
violated-directive
The name of the policy section that was violated.

위반 보고 예제

Let's consider a page located at http://example.com/signup.html. It uses the following policy, disallowing everything but stylesheets from cdn.example.com.
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
The HTML of signup.html looks like this:
<!DOCTYPE html>
<html>
  <head>
    <title>Sign Up</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Content ...
  </body>
</html>
Can you spot the mistake? Stylesheets are only allowed to be loaded from cdn.example.com, yet the website tries to load one from its own origin (http://example.com). A browser capable of enforcing CSP will send the following violation report as a POST request to http://example.com/_/csp-reports, when the document is visited:
{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}

As you can see, the report includes the full path to the violating resource in blocked-uri. This is not always the case. For example, when the signup.html would attempt to load CSS from http://anothercdn.example.com/stylesheet.css, the browser would not include the full path but only the origin (http://anothercdn.example.com). The CSP specification gives an explanation of this odd behaviour. In summary, this is done to prevent leaking sensitive information about cross-origin resources.

브라우저 호환성

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
Content-Security-PolicyChrome Full support 25
Full support 25
Full support 14
Alternate Name
Alternate Name Uses the non-standard name: X-Webkit-CSP
Edge Full support 14Firefox Full support 23
Full support 23
Full support 4
Alternate Name
Alternate Name Uses the non-standard name: X-Content-Security-Policy
IE Full support 10
Notes Alternate Name
Full support 10
Notes Alternate Name
Notes Only supporting 'sandbox' directive.
Alternate Name Uses the non-standard name: X-Content-Security-Policy
Opera Full support 15Safari Full support 7
Full support 7
Full support 6
Alternate Name
Alternate Name Uses the non-standard name: X-Webkit-CSP
WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 23Opera Android Full support YesSafari iOS Full support 7
Full support 7
Full support 5.1
Notes
Notes X-Webkit-CSP
Samsung Internet Android Full support Yes

Legend

Full support  
Full support
See implementation notes.
See implementation notes.
Uses a non-standard name.
Uses a non-standard name.

A specific incompatibility exists in some versions of the Safari web browser, whereby if a Content Security Policy header is set, but not a Same Origin header, the browser will block self-hosted content and off-site content, and incorrectly report that this is due to a the Content Security Policy not allowing the content.

같이 보기