Content Security Policy (CSP) Introduction
The traditional Web security should mainly be the same origin policy ). Website a's Code cannot access website B's data. Each domain is isolated from other domains and creates a security sandbox for developers. In theory, this is a very clever practice, but in practice, attackers use various tricks to overturn this protection.
XSS attackers inject malicious code into the conventional data of the website, so that they can bypass the same source policy of the browser. The browser believes all the code from the security domain. XSS cheat sheet is an old but representative attack method. Once the attacker successfully injects the code, the game is basically over, and the user data is undoubtedly leaked. We are eager to prevent such attacks.
This tutorial points out a brand new defense method: Content Security Policy (CSP), which is a brand new active defense system provided by html5. CSP can effectively reduce XSS attacks, of course, browser support is required first.
Whitelist
The main problem with browsers is that they cannot distinguish whether scripts are from their own applications or malicious injection by third-party attackers, which is precisely exploited by attackers. For example, Google's+ 1The button will load and execute a script from the https://apis.google.com/js/plusone.js that we trust, but we cannot expect the browser to differentiate scripts from api.google.com from safe, insecure from apis.evil.example.com. All files are downloaded and executed by the browser. CSP defines the content-security-policy HTTP header to create a source whitelist for your content. The browser only allows resource and code execution in the whitelist domain. In this way, even if the attacker finds a vulnerability injection script, the script cannot be executed even if it is not in the whitelist.
In the previous example, we continue to explain that we trust the api.google.com code and we can define our protocol in this way.
Content-Security-Policy: script-src ‘self‘ https://apis.google.com
So easy, as the name suggests, script-Src controls the script label-related policy, in the above example, we specify the 'self 'and https://apis.google.com as his value, the browser only downloads and executes scripts for the domain and https://apis.google.com.
If there are other scripts, the browser will throw the following exception. Attackers can only get the following results if they inject the script:
Policy supports multiple resources
In addition to script resources, CSP also provides multiple commands to control the loading of various resources. The usage is similar to that of script-Src. Let's take a quick look at these commands:
Restrict the use of xhr, websockets, and eventsource connection sources.
Download source of the specified font.
Specifies the Connection source that the frame can embed.
Specifies the image loading source.
Specifies the video and audio data sources.
Specify the Connection source of flash and Other plug-ins.
Specify the link connection source. Similar to script-Src.
By default, if you do not specify the value of these commands, all sources are allowed, such as font-Src: *, which is equivalent to not writing font-Src.
You can also override the default value, as long as you use default-Src. For example, if default-Src: https://example.com is specified but font-Src is not specified, your font-Src can only be loaded from the https://example.com. In the previous example, only script-Src is specified, which means that image, font and other resources can be loaded from anywhere else.
You can specify multiple or one command for your web application. You only need to list these values in the HTTP header. Different values are separated. But if you write a script-Src https://host1.com; script-Src: https://host2.com, the Second Script-Src won't work, and the correct way is: script-Src https://host1.com https://host2.com.
Another example: if all your static resources come from one CDN, And you know there will be no frame or other plug-ins. You can write
Content-security-policy: default-Src https://cdn.example.net; frame-Src 'none'; object-Src: 'none'
Detailed Implementation
X-WebKit-CSP and X-content-security-policy are all previous HTTP headers. In modern browsers (except IE, all content-security-policy headers with no prefix are supported.
The CSP policy requires that each page request carry the content-security-policy header, which provides a lot of flexibility. You can even determine when to add the CSP policy based on the conditions and when not.
The source list of the Protocol is also flexible, you can specify the Protocol (data:, https :), or only specify the host name :( example.com, allow any protocol, any port), or full limit (https://example.com: 443 ). You can even use wildcards,://.Example.com: *, matches any subdomain of example, any protocol and port,Note: wildcard characters are not allowed for example.com..
The following four keywords can also be used in the source list:
None match.
Matches the current domain, excluding subdomains.
Allow inline JavaScript and CSS.
Allows execution of Eval, new function, and so on.
These keywords need to be referenced in single quotes. If they are not referenced, they will be considered as domain names.
Sandbox
The sandbox is also worth mentioning. The role of a sandbox is a little different. It is mainly used to limit what operations a page can do, rather than what resources can be loaded. If the sandbox command is specified, the page will be treated as an IFRAME page: it must be the same source, and form submission is prohibited. These contents are beyond the scope of this article. For details, visit the following link: "sandboxing Flag Set" section of the HTML5 spec.
Inline code is risky
CSP is based on a whitelist. This method clearly identifies which resources are recognized and which cannot. However, this method cannot solve a major problem: inline Script Injection. If attackers can inject a script:
<script>sendMyDataToEvilDotCom();</script>
The browser has no mechanism to distinguish between rational code and malicious code. CSP can solve this problem:Disable all inline scripts. It includes not only the values in the <SCRIPT> label, but also the inline events and javascript: [Code] methods. If your code is written in this way, you need to make some changes.
For example:
<script> function doAmazingThings(){ alert(‘YOU ARE AMAZING‘); }</script><button onclick="doAmazingThings();">AM I amazing?</button>
Change
<!-- amazing.html --><script src=‘amazing.js‘></script><button id=‘amazing‘>Am I amazing?</button>
// amazing.jsfunction doAmazingThings() { alert(‘YOU AM AMAZING!‘);}document.addEventListener(‘DOMContentReady‘, function () { document.getElementById(‘amazing‘) .addEventListener(‘click‘, doAmazingThings);});
The rewritten code is more compliant with the standard, and CSP can also run well. External resources can be better cached and compressed. This is a good coding habit.
Inline style has the same processing method.
If you are determined to use an inline script or style, you can use 'unsafe-inline' as the values of script-Src and style-Src, but we do not recommend this. Disabling inline scripts and styles is a security mechanism provided by CSP and a compromise worth making.
Eval
Although attackers cannot directly inject scripts, attackers may use strings to confuse them with other browsers, such as setinterval ([String],...). it may eventually lead to execution of some malicious attack code. The CSP's method to avoid compromise risks is to completely disable it.
- Use native JSON. parse to avoid using eval
Native JSON. parse is absolutely secure, and all browsers except IE8 and earlier support it.
Override setTimeout
setTimeout("document.querySelector(‘a‘).style.display=‘none‘;",10);
Rewrite
setTimeout(function(){ document.querySelector(‘a‘).style.display = ‘none‘; },10);
Avoid running template tools
Many template libraries use new function () to accelerate the generation of runtime templates. Although this practice is very good, it brings risks. Some databases support CSPs without new functions and downgrade to versions without eval.
If the template you use supports handlebars, it will be faster and safer than the fastest runtime compilation template. Similarly, if you must use this text-to-JavaScript method, add 'unsafe-eval' to script-Src. Not enough.
Reporting
CSP is a good mechanism to prevent untrusted resources from being executed on the client, but it will be even better if some reports can be returned to the server. In this way, you can immediately locate some attacks and injections. Report-Uri allows you to specify an address.
Content-Security-Policy: default-src ‘self‘; report-uri /my_amazing_csp_report_parser;
The report content is as follows:
{ "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" }}
The report contains a large amount of information to help you locate the attack, including the page where the attack occurred, Referer, block-Uri, And the violating policies and your defined policies.
Report-only
Content-Security-Policy-Report-Only: default-src ‘self‘; ...; report-uri /my_amazing_csp_report_parser;
In this way, only one report is sent to the background without stopping scripts and other resources.
Actual use
CSP is well supported in chrome 16 +, Safari 6 +, and Firefox 4 +. Partially supported on ie10. Twitter's case study and Facebook are both commercially available.
Use Case #1: Social Media Widgets
Google's+ 1 buttonIncludes a section from the https://apis.google.com, and an embedded IFRAME from the https://plusone.google.com. A basic policy is: script-Src https://apis.google.com; frame-Src https://plusone.google.com.
Facebook'sLike buttonThere are multiple implementation methods. I recommend using IFRAME.
frame-src https://facebook.com
The default IFRAME of Facebook is // Facebook.com by default. Please Use https as shown. If you do not need to use HTTPS as much as possible.
Use Case #2 lockdown
If you are building a bank website, you must ensure that all resources except your own scripts are strictly prohibited from being executed. First, you can use default-Src 'none '.
Bank pictures, styles and scripts are from CDN: https://cdn.mybank.net, and xhr to https://api.mybank.com/will pull a lot of data, frame is also used, but only load the page of the domain, no third domain. There is no flash or fonts on the website. A strict CSP can be written as follows:
Content-Security-Policy: default-src ‘none‘; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; frame-src ‘self‘
Use Case #3 SSL only
The administrator of a wedding ring forum wants to ensure that all resources are loaded by using SSL, but it is unrealistic to change all of them because they have a large number of inline scripts. We can design the following rules:
Content-Security-Policy: default-src https; script-src https: ‘unsafe-inline‘; style-src https: ‘unsafe-inline‘
Future
Content Security Policy 1.0 is W3C candidate recommendation, which is quickly implemented by the browser. W3C is currently drafting new features of Content Security Policy 1.1 worth noting:
- Supports inline script and Style
Although we should try to avoid using inline scripts and styles, we still need to take into account the existing site, so 1.1 using nouces and hashes is safe to ensure inline scripts and styles.
- The policy can be added using Meta.
Support adding meta tags to CSP policies
<meta http-equiv="Content-Security-Policy" content="[POLICY GOES HERE]">
You can even use JavaScript to inject a meta CSP policy.
In the future, you will be able to use JavaScript to query and modify CSP policies. You can specify different policies to deal with different situations.
Some new commands will be added, including: Plugin-types restricts that the plug-in can load the MIME type. Form-Action Form submission target address limit.
This article is Alan's translation, original article link: http://www.html5rocks.com/en/tutorials/security/content-security-policy/