I have talked a lot about Same Origin Policy in one of my post on “Same Origin Policy”. Same Origin Policy prevents my kinds of attacks and provides a secure environment for web developers to build web applications. But in that post I also explained some ways by which we can bypass same origin policy. So we can say the same origin policy provided by the browser is not enough to prevent XSS attacks. In this post we will look at Content Security Policy which can block XSS attacks and provide more security layer to Same Origin Policy.
What is Content Security Policy(CSP)?
CSP is a technique by which website administrator provides lists of trusted sources to the browser from which content like JavaScript, CSS, HTML Frames, Fonts, Images and embeddable objects (Java applets, ActiveX, Audio and Video) can be loaded into a page.
Sources information can be provided to browser via HTTP response header or meta tags.
Passing sources list via HTTP Header
Header | Chrome | Firefox | Safari | IE |
---|---|---|---|---|
Content-Security-Policy | 25+ | 23+ | 7+ | – |
X-Content-Security-Policy | – | 4.0+ | – | 10+ |
X-Webkit-CSP | 14+ | – | 6+ | – |
We can provide source list to browser via the above headers. For compatible in all browser we can use Content-Security-Policy and X-Content-Security-Policy together.
In meta tag attribute http-equiv we can assign the header name and assign content attribute to header value.
Directives
We need to assign CSP header a list of directive and associated a directive value. Directive represent content type and its value represents trusted source.
These are the directives for CSP:
- default-src: Sources for all types of content
- script-src: Sources for javascript files
- style-src: Sources for stylesheets
- img-src: Sources of images
- connect-src: Sources for XMLHttpRequest, WebSocket and EventSource
- font-src: Sources for fonts
- object-src: Sources for <object>, <embed> and <applet>
- media-src: Sources for <audio> and <video>
- frame-src: Sources for frames
- sandbox: Browser treats the page like it is loaded inside a sandboxed iFrame. To learn more about sandboxed iFrame follow this links Link1 Link2
- report-uri: Browser posts a report on policy failures to specified URL. We can also append “-Report-Only” to the CSP header to not block anything just send reports.
Directive Values
All those attributes that end with -src support values called as source list values.
- * -> Wildcard, allows everything.
- ‘none’ -> Prevents loading resources from any source.
- ‘self’ -> Allows loading resources from the same origin (same scheme, host and port).
- data: -> Allows loading resources via the data scheme (example: Base64 encoded images).
- domain.example.com -> Allows loading resources from the specified domain.
- *.example.com -> Allows loading resources from any subdomain under example.com
- https://my.example.com -> Allows loading resources only over HTTPS matching the given domain.
- https: -> Allows loading resources only over HTTPS on any domain.
- ‘unsafe-inline’ -> Allows use of inline javascript. I will get more into it later.
- ‘unsafe-eval’ -> Allows use of dynamic code evaluation.
For sandbox directive we can pass the following values:
- allow-forms -> This allows submission of forms in the page.
- allow-same-origin -> In sandboxed mode document has no access to its origin cookies or any other storage. This value allows use of cookies and other stored data for the origin.
- allow-top-navigation -> Allows use of window.top.location and target=”_top”. Without this value there will be no effect.
- allow-scripts -> Allows script execution.
- allow-popups -> Sandboxed document will create new window or dialogs when window.open and target=”_blank” is used. This value allows creation of new windows and dialogs.
‘unsafe-inline’ and ‘unsafe-eval’ values
If CSP header is included in the HTTP response than browser doesn’t allow inline javascript and dynamic code evaluation.
Inline javascript comprises of <script></script>, onclick attribute and href values starting with “javascript:” are blocked. Browser forces all javascript to reside in separate files served from a trusted domain. We can bypass this restriction by assigning script-src attribute to unsafe-inline value.
Dynamic code evaluation comprises of use of eval() function and string arguments for both setTimeout and setInterval. Thus restriction can be bypassed by assigning script-src attribute to unsafe-eval.
Points to remember
Multiple values can be space separated.
* and ‘none’ cannot be used with any other values.
‘self’, ‘none’, ‘unsafe-inline’ and ‘unsafe-eval’ needs to be put inside single quotes.
Examples
If we keep the CSP header empty than it follows Same Origin Policy only. And it still it restricts inline and dynamic javascript.
If we want to allow everything from the same origin and execution of inline and dynamic javascript. Then,
or
If the page is loaded inside an iFrame or not but you want to make it sandboxed and also allow form submission and data access. Then,
For development purpose you might not want to want to block anything but only get reports on possible blocks. Than
You want to block and also get reports then:
Conclusion
CSP provides the best XSS protection. I tried to cover all possible directives and values related to CSP. You can try playing around with it. And also I recommend you to use CSP to protect your websites.