www.ruanyifeng.com/blog/2016/0…

Content Security Policy tutorial

Share button

Author: Ruan Yifeng

Date: September 13, 2016

Cross-domain scripting attack XSS is the most common and harmful web security vulnerability.

It takes a lot of programming to prevent them, and it’s a lot of trouble. Many people ask, can fundamentally solve the problem, the browser automatically prohibit external injection of malicious scripts?

This is where Content Security Policy (CSP) comes in. This article details how to use CSP to prevent XSS attacks.

A list,

The essence of CSP is whitelisting. The developer clearly tells the client which external resources can be loaded and executed, which is equivalent to providing a whitelist. Its implementation and execution are all done by the browser, and the developer only needs to provide the configuration.

CSP greatly enhances the security of web pages. Even if an attacker discovers a vulnerability, he cannot inject scripts unless he also controls a whitelisted trusted host.

There are two ways to enable CSP. One is through the content-security-Policy field of the HTTP header.

Content-Security-Policy: script-src 'self'; object-src 'none';
style-src cdn.example.org third-party.org; child-src https:
Copy the code

The other is through a
tag on a web page.

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
Copy the code

In the code above, CSP does the following configuration.

  • Script: Trust only the current domain name
  • <object>Tags: Do not trust any URLS, that is, do not load any resources
  • Style sheets: Trust onlycdn.example.organdthird-party.org
  • Frame: The frame must be loaded using HTTPS
  • Other resources: No restrictions

When enabled, external resources that do not comply with CSP are blocked from loading.

Chrome error message.

Firefox error message.

Limit your options

CSP provides a number of limiting options, covering all aspects of security.

2.1 Resource Loading Restrictions

The following options restrict the loading of various resources.

  • Script-src: external script
  • Style-src: style sheet
  • Img SRC: image
  • Media-src: media files (audio and video)
  • Font-src: font file
  • Object-src: plug-ins (such as Flash)
  • The child – SRC: framework
  • Frame-rooted: an embedded external resource (such as,,, and)
  • Connect-src: HTTP connection (via XHR, WebSockets, EventSource, etc.)
  • worker-src:workerThe script
  • Manifest-src: indicates the manifest file

2.2 the default – the SRC

Default-src is used to set the default values of the preceding options.

Content-Security-Policy: default-src 'self'
Copy the code

The above code restricts all external resources to be loaded only from the current domain name.

If you set a single restriction (e.g., font-src) and default-src at the same time, the former overwrites the latter, meaning font files use font-src values and other resources use default-src values.

2.3 the URL limit

Sometimes web pages are linked to other urls, which can be restricted.

  • Frame-rooted: a page that restricts the embedding of a frame
  • base-uri: limiting the<base#href>
  • form-action: limiting the<form#action>

2.4 Other Restrictions

Other security-related functions are also included in the CSP.

  • Block-all-mixed-content: HTTPS pages cannot load HTTP resources (browser default enabled)
  • Upgrade-insecure -requests: automatically replaced all HTTP links on web pages that loaded external resources with HTTPS
  • Plugin-types: Limits the plug-in formats that can be used
  • Sandbox: Restrictions on browser behavior, such as no pop-ups, etc.

2.5 the report – a uri

Sometimes, we want to not only prevent XSS, but also document such behavior. The report-URI is used to tell the browser which url to report the injection behavior to.

Content-Security-Policy: default-src 'self'; . ; report-uri /my_amazing_csp_report_parser;Copy the code

The above code specifies that the injection behavior is reported to the /my_amazing_csp_report_parser URL.

The browser uses the POST method to send a JSON object, as shown in the following example.

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}
Copy the code

Third, the Content of ws-security – Policy – Report – Only

In addition to content-security-policy, there is also a content-security-policy-report-only field, which does not enforce the restriction option, but Only logs the violation of the restriction.

It must be used in conjunction with the report-URI option.

Content-Security-Policy-Report-Only: default-src 'self'; . ; report-uri /my_amazing_csp_report_parser;Copy the code

4. Option value

Each restriction option can set the following values, which make up the whitelist.

  • Host name:example.org.https://example.com:443
  • The path name:example.org/resources/js/
  • Wild card:*.example.org.*://*.example.com:*(Indicates any protocol, any subdomain name, or any port)
  • Agreement:https:,data:
  • The keyword'self': Indicates the current domain name
  • The keyword'none': Disables loading of any external resources and requires quotation marks

Multiple values can also be juxtaposed, separated by Spaces.

Content-Security-Policy: script-src 'self' https://apis.google.com
Copy the code

If the same restriction option is used more than once, only the first restriction takes effect.

Script-src https://host1.com; Script-src https://host2.com # Correct way to write script-src https://host1.com https://host2.comCopy the code

If no restriction option is set, any value is allowed by default.

Special values of script-src

In addition to regular values, script-src can also set special values. Note that the following values must be enclosed in single quotes.

  • 'unsafe-inline': allows page embedding to be performed&lt; script>Tag and event listener functions
  • unsafe-eval: allows strings to be executed as code, such as usingeval,setTimeout,setIntervalandFunctionEtc. Function.
  • Nonce value: Each HTTP response gives an authorization token that the embedded script must have before it can be executed
  • Hash value: Lists the hash values of the script code that can be executed. The script can be executed only when the hash values of the embedded script on the page match.

An example of a nonce value is as follows: when the server sends a web page, it tells the browser a randomly generated token.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
Copy the code

The page is embedded with scripts that must have this token to execute.

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa>
  // some code
</script>
Copy the code

An example of a hash value is as follows. The server gives a hash value for the code that is allowed to execute.

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
Copy the code

The following code will allow execution because the hash values match.

<script>alert('Hello, world.'); </script>Copy the code

Notice that when you compute the hash value,

In addition to the script-src option, the nonce value and hash value can also be used with the style-src option to control the style sheet embedded in the page.

Six, pay attention

(1) Script-src and object-src are mandatory unless default-src is set.

As long as an attacker can inject scripts, other restrictions can be circumvented. Object-src is required because external scripts can be executed in Flash.

(2) script-src cannot use the unsafe-inline keyword (unless accompanied by a nonce value), and data:URL cannot be set.

Here are two examples of malicious attacks.

<img src="x" onerror="evil()">
<script src="data:text/javascript,evil()"></script>
Copy the code

(3) Special attention must be paid to the JSONP callback function.

<script src="/path/jsonp? callback=alert(document.domain)//"> </script>Copy the code

In the above code, even though the loaded script is from the current domain, an attacker can still execute malicious code by overwriting the callback function.

7. Reference links

  • CSP Is Dead, Long Live CSP! , by Lukas Weichselbaum
  • An Introduction to Content Security Policy, by Mike West

(after)

Document information