CommentsThe emergence of HTML5 has attracted more and more attention in network security. What improvements does the Web provide to network security? How can we face increasingly dangerous cyber fraud and attacks? The following article describes W3C's latest solution to this problem. In the future, I will conduct security policies on HTML5 content World Wide Web Based on XSS, P3P, same-origin policy, CORS (cross-origin resource sharing) and CSP. For example, the Code for www.jb51.net can only access the data for www.jb51.net, but has no permission to access the http://www.baidu.com. Each source is separated from other parts of the network, creating a secure sandbox for developers. Theoretically, this is perfect, but now attackers have found a smart way to destroy the system.
This is an XSS cross-site scripting attack that bypasses the same-origin policy through fake content and spoofing clicks. This is a big problem. If attackers successfully inject code, a considerable amount of user data will be leaked.
Now we will introduce a brand new and effective security defense Policy to mitigate this risk. This is the Content Security Policy (CSP ).
Source whitelist
The core of XSS attacks is that the browser cannot distinguish whether scripts are injected by a third party or are part of your application. For example, the Google + 1 button will. The browser downloads and executes a page request for Arbitrary Code regardless of its source.
CSP defines the Content-Security-PolicyHTTP header to allow you to create a whitelist of trusted sources so that the browser can only execute and render resources from these sources, instead of blindly trusting all the content provided by the server. Even If attackers can find the vulnerability to inject scripts, the source is not included in the whitelist, so it will not be executed.
The above Google + 1 button is used as an example. Because we believe that apis.google.com provides valid code and ourselves, we can define a policy that allows the browser to execute only scripts from one of the following two sources.
Content-Security-Policy: script-src 'self 'https://apis.google.com
Is it easy? Script-src can control script-related permissions for specified pages. In this way, the browser only downloads and executes scripts from the http://apis.google.com and the page itself.
Once this policy is defined, the browser will throw an error when detecting the injection code (note the browser ).
Content Security policy applies to all common resources
Although script resources are the most obvious security risks, CSP also provides a rich set of instruction sets that allow page control to load various types of resources, such as the following types:
Content-src: Restrict connection types (such as XHR, WebSockets, and EventSource)
Font-src: controls the source of the network font. For example, Google's network fonts can be used through the font-src https://themes.googleusercontent.com.
Frame-src: lists the sources of frames that can be embedded. For example, the frame-src https://youtube.com only allows video embedding on YouTube ..
Img-src: defines the source of the loaded image.
Media-src: restrict the sources of video and audio.
Object-src: restrict the source of Flash and Other plug-ins.
Style-src: similar to Script-src, it only applies to css files.
By default, all settings are enabled without any restrictions. You can separate multiple commands with semicolons, but in the form of a script-src https://host1.com; script-src https://host2.com, the second command will be ignored. The correct syntax is the script-src https://host1.com https://host2.com.
For example, you have an application that needs to load all resources from a content delivery network (CDN, such as a https://cdn.example.net) and knows that no frame or plug-in content is needed, your policy may be as follows:
Content-Security-Policy: default-src https://cdn.example.net; frame-src 'none'; object-src 'none'
Details
The HTTP header I used in this example is Content-Security-Policy, but modern browsers have provided support through prefixes: Firefox uses x-Content-Security-Policy, webKit uses X-WebKit-CSP. In the future, we will gradually transition to a unified standard.
Policies can be set based on different pages, which provides great flexibility. Because some of your websites may have Google + 1 buttons, while others do not.
The source list of each command can be quite flexible. You can specify the mode (data:, https :), or specify the host name in a range (example.com, it matches any source, any mode, and any port on the host, or specifies a complete URI (https://example.com: 443, especially for https protocol, example.com domain name, port 443 ).
You can also use four keywords in the source list:
"None": you may expect nothing to match
"Self": Same as the current source but does not contain subdomains
"Unsafe-inline": Allow inline Javascript and CSS
"Unsafe-eval": a mechanism that allows text to JS, such as eval
Note that quotation marks are required for these keywords.
Sandbox
Here is another instruction worth discussing: sandbox. It is somewhat different from other commands. It mainly controls the actions taken on the page, rather than the resources that can be loaded on the page. If this attribute is set, the page is displayed as a frame with the sandbox attribute set. This has a great impact on the page, such as preventing form submission. This is beyond the scope of this article, but you can find more information in the "sandbox flag settings" section of the HTML5 standard.
Harmful Inline code
CSP is based on the source whitelist, but it cannot solve the biggest source of XSS attacks: inline Script Injection. If attackers can inject script tags containing harmful code (<script> sendMyDataToEvilDotCom (); </script>), the browser does not have a good mechanism to distinguish this tag. CSP can only solve this problem by completely disabling inline scripts.
This prohibition includes not only the script tag embedded in the script, but also the inline event handler and javascrpt: URL. You need to put the content of the script tag in an external file and replace javascript with <... Onclick = "[JAVASCRIPT]">. For example, you may put the following form:
<Script>
Function doAmazingThings (){
Alert ('You am amazing! ');
}
</Script>
<Button onclick = 'doamazingthings (); '> Am I amazing? </Button>
Rewrite to the following format:
<! -- Amazing.html -->
<Script src = 'amazing. js'> </script>
<Button id = 'amazing'> Am I amazing? </Button>
// Amazing. js
Function doAmazingThings (){
Alert ('You am amazing! ');
}
Document. addEventListener ('domcontentready', function (){
Document. getElementById ('amazing ')
. AddEventListener ('click', doAmazingThings );
});
Whether or not CSP is used, the above Code actually has greater advantages. Inline JavaScript completely blends the structure and behavior. You should not do this. In addition, external resources are easier to cache in the browser, making it easier for developers to understand and compile and compress. If you use external code, you will write better code.
Inline styles must be processed in the same way. Both style attributes and style labels must be extracted to external style sheets. This prevents various magical Data leaks.
If you must have inline scripts and styles, you can set the 'unsafe-inline value for the script-src or style-src attribute. Do not do this. Disabling inline scripts is the maximum security guarantee provided by CSP. Disabling inline styles can make your applications more secure and robust. This is a trade-off, but it is worth it.
Eval
Even If attackers cannot inject scripts directly, they may trick your application into converting the inserted text into executable scripts and self-executing them. Eval (), newFunction (), setTimeout ([string],...), and setInterval ([string],...) may all become the carriers of this risk. CSP's strategy for this risk is to completely block these carriers.
This has some impact on the way you build the application:
Parse JSON with built-in JSON. parse without relying on eval. Browsers later than IE8 support local JSON operations, which is completely secure.
Use inline functions instead of strings to override the call methods of setTimeout and setInterval. For example:
SetTimeout ("document. querySelector ('A'). style. display = 'none';", 10 );
It can be rewritten:
SetTimeout (function () {document. querySelector ('A'). style. display = 'none' ;}, 10 );
Avoid inline templates during running: Many template libraries use new Function () to accelerate template generation. This is great for dynamic programs, but it is risky for malicious texts.
Report
CSP can block untrusted resources on the server side, which is very useful for users, but it is very useful for us to obtain various notifications sent to the server, in this way, we can identify and fix any malicious script injection. Therefore, you can use the report-uri command to instruct the browser to send the interception report in JSON format to an address.
Content-Security-Policy: default-src 'self ';...; report-uri/my_amazing_csp_report_parser;
The report looks like the following:
{
"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-service 'https://apis.google.com ",
"Original-policy": "script-src 'self 'https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
}
}
The information contained in it will help you identify interception situations, including document-uri, referrer, and blocked-uri ), violated-ctictive and original-policy ).
Practical usage
CSP is now available on Chrome 16 + and Firefox 4 + browsers, and it is expected to receive limited support on IE10. Safari is not supported yet, But WebKit is available for every night build, so Safari is expected to provide support in the following iterations.
Let's take a look at some common use cases:
Case 1: Social Media Widgets
Google + 1 button includes scripts from the https://apis.google.com and iframe embedded from the https://plusone.google.com. Your policy needs to include these sources to use the Google + 1 button. The simplest strategy is the script-src https://apis.google.com; frame-src https://plusone.google.com. You also need to ensure that the JS fragments provided by Google are stored in external JS files.
Facebook's Like button has many implementations. I suggest you stick to the iframe version because it can be well isolated from other parts of your site. This requires the use of the frame-src https://facebook.com directive. Please note that, by default, the iframe Code provided by Facebook uses a relative path // facebook.com, please change this code to a https://facebook.com, HTTP you do not have to use.
Twitter's Tweet buttons depend on scripts and frames, both from the https://platform.twitter.com (Twitter provides relative URLs by default, Please edit the code when copying to specify as HTTPS ).
Similar situations exist on other platforms and can be solved similarly. We recommend that you set default-src to none, and then check the console to check which resources you need to use to ensure that the widget works properly.
It is very easy to use multiple widgets: you only need to merge all the policy commands and remember to put the settings of the same command together. If you want to use the above three widgets, the policy will look like the following:
Script-src https://apis.google.com https://platform.twitter.com; frame-src https://plusone.google.com https://facebook.com https://platform.twitter.com
Case 2: Defense
Suppose you visit a bank website and want to ensure that only the resources you need are loaded. In this case, set a default permission to block all content (default-src 'None') and create a policy from this.
For example, a bank website needs to load images, styles, and scripts from the https://cdn.mybank.net's CDN, and connect to https://api.mybank.com/to pull various types of data, and then use frameworks, but frameworks are not third-party webpages. There is no Flash, Font, or other content on the website. In this case, we can send the strictest CSP header:
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'
Case 3: only use SSL
The administrator of a wedding ring forum wants all resources to be loaded in a safe way, but does not want to write too much code. rewriting a large number of third-party Forum inline scripts and style code exceeds his ability. Therefore, the following policies will be very useful:
Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'
Although https is specified for default-src, scripts and styles are not automatically inherited. Each Command will completely overwrite the default resource type.
Future
W3C's Web Application Security workgroup is developing details of content security policy specifications. Version 1.0 is about to enter the final revision phase, which is very close to the content described in this article. Public-webappsec @ Contact List is discussing Version 1.1, and browser vendors are also striving to consolidate and improve CSP implementation.
CSP 1.1 has some interesting points on the drawing board, which should be listed separately:
Add Policy through meta tag: the preferred setting method of CSP is the HTTP header, which is very useful, but it is more direct through tag or script settings, but it is not final yet. WebKit has implemented the permission setting feature through the meta element, so now you can try the following settings in Chrome: add <metahttp-equiv = "X-WebKit-CSP" content = "[policy goes here]"> to the document header.
You can even add a policy through a script at runtime.
Dom api: if CSP adds this feature in the next iteration, you can use Javascript to query the current security policy of the page and adjust it based on different situations. For example, if eval () is available, your code implementation may be slightly different. This is very useful for the authors of the JS framework, and the API specification is still very uncertain. You can find the latest iteration version in the script interface section of the Specification Draft.
New commands: many new commands are being discussed, including script-nonce: inline scripts can be used only for explicitly specified script elements; plugin-types: this will limit the type of the plug-in; form-action: allows the form to be submitted only to a specific source.
If you are interested in the discussion of these future features, you can read the archive of the mail list or add it to the Mail list.
This article translated from: http://www.html5rocks.com/en/tutorials/security/content-security-policy/
From: Jiang Yujie's blog