Content Security Policy
The entire web application security model is built on the idea of “Same Origin Policy” which restricts the content of one domain being accessed by another domain. However, the attackers have found various ways to get over this policy and have found several ways to bypass this policy. By subverting this policy, the attackers have introduced various attacks like cross-site scripting and other data injection attacks. In order to mitigate such attacks, the concept of “content – security – policy” was brought into picture.
“Content Security Policy” is a declarative policy that allows the application developers to inform the client about the sources from which the application can load the resources. Content security policy does not help as a first line of defense against code injection attacks, but it can be best used as defense-in-depth to reduce the harm caused by such attacks. To take advantage of this policy, the application developers need to make use of “Content-Security-Policy” HTTP header.
Content security policy header was originally developed by Mozilla Foundation. Experimental implementations of this header in various browsers was done by names like X-Webkit-CSP in chrome , X-Content-Security-Policy in browsers like Mozilla, SeaMonkey, etc. “Content-Security-Policy” is the standard header name proposed by the W3C document.
Workings of the CSP header:
The content-security-policy header is sent in the server response. On encountering this header in the response, the client judges from where or from where not the content should be loaded in that page. This is done by the browser by using the directives and the values present in the CSP response header.
CSP header is applicable per page. Hence, it is advised to add this header for every response.
CSP directives and their usage:
CSP provides a wide range of directives each one specific for a content type. The directives provided by content security policy are as follows:
Before getting into the directives, let us look at few basic keywords that are used as part of CSP directive values.
– * (asterisk) – allow anything
– none : matches nothing.
– self: matches the current origin, but not its subdomains.
– https: allow resources only over HTTPS
Now, let us look into each of the content security policy directives with related examples –
Script –Src: Script-src is a directive that controls a set of script-related privileges for a specific page. It restricts which scripts the protected resource can execute and controls other resources, such as XSLT style sheets, which can cause the user agent to execute the scripts.
Grammar: Content-Security-Policy: script-src directive value;
A probable example could be as follows –
Content – Security – Policy: script-src ‘self’;
This type of header would restrict scripts being executed from different domains. Only the scripts that belong to the same domain as the domain of the page will be executed.
Similarly, we can have script – src value set to other directive values as follows –
-> Content – Security – Policy: script-src www.abc.com;
Such a setting would allow scripts to get executed only when they belong to the domain specified. Here in this example, the script belonging to the “abc.com” domain would be executed.
-> Content – Security – Policy: script-src ‘unsafe-inline’;
This would allow all the inline scripts present on the page to be executed by the browser.
-> Content – Security – Policy: script-src ‘unsafe-eval’;
With this directive value set, the browser would allow all the eval functions to be executed without any restriction.
One can always set multiple directive values to a directive.
Example- Content – Security – Policy: script-src ‘self’, https://www.xyz.com;
In the above example, we have specified self and xyz.com domain as valid sources of scripts. Therefore, the browser would interpret this and allow execution of scripts to be executed only if they belong to same domain or xyz.com domain.
In case there is some script that is interpreted to be from an invalid source according to the browser, the browser would display an error message as follows –
Refused to load the script ‘script-uri’ because it violates the following Content Security Policy directive: “CSP directive set by you“.
This error message may vary according to the browser.
Connect – Src:
This directive defines valid sources for fetching the XMLHttpRequest, WebSocket, and EventSource connections. These connections may be to external server to send/receive information, eventSource open HTTP connections to a server for receiving push notifications, WebSockets for communication between and a server, and XMLHttpRequests to make arbitrary HTTP requests on your behalf. The connect-src directive allows you to ensure that these sorts of connections are only opened to origins you trust.
In case the connect-src is absent, then the browser looks for default-src or it will take the default value to be * and will fetch all the connections.
Content – Security – Policy : connect-src directive value;
An example could be- Content – Security – Policy: connect-src ‘self’ , www.xyz.com;
The above setting of the connect-src directive would allow the connections only from same domain or the xyz.com domain.
Frame-src restricts the sources from where a resource can be embedded into the frame. It decides the valid sources of content for nested contexts, web workers.
Content – Security – Policy: frame-src value;
Example: Content – Security – Policy : frame-src www.test.com;
This would instruct a browser that the content in a frame can be loaded only from test.com domain.
The Frame-src directive is now deprecated and most of the browsers are not implementing it now a days. Instead of this, child –src is being implemented.
Child –Src also does the same work as the frame-src directive. The grammar is also same as the frame-src directive.
This directive specifies valid parents that may embed a page using the <frame> and <iframe> elements.
Content – Security – Policy: frame-ancestors value;
Example: Content – Security – Policy : frame-ancestors www.test.com;
This would instruct the browser that the page can be loaded into a frame only of the parent frame is from test.com domain.
This directive is used to implement restrictions on sources from where the images can be loaded into the protected resource. Whenever the application tries to retrieve any image and the source from where the image is being retrieved does not match the one specified in the img-src directive, then the browser might throw an error.
Content – Security – Policy: img-src directive value;
Example: Content – Security – Policy: img – src ‘self’, www.test.com
By setting this directive as above, it instructs the browser that the images belonging to the same domain as that of the page and images from test.com can also be loaded.
Similar to the img-src directive, the media-src directive implements restrictions on sources from where the media files like audio or video files can be loaded into the protected resource. Whenever the application tries to retrieve any media apart from the one specified in the media-src directive, and then the browser might throw an error.
Content – Security – Policy: media-src directive value;
Example: Content – Security – Policy: media – src ‘self’, www.test.com
This setting would load media only from the self domain or test.com domain.
Object-src: The Object -src directive restricts the valid sources from where the protected resource can load data for embedded elements or applets or objects or load any plug-in.
Grammar: Content – Security – Policy: object-src directive value;
Example: Content – Security – Policy: object-src ‘self’;
This would allow plugins to be loaded only from the same domain as the page and also other applet data or object data to be loaded only from the same domain.
Style-src: This directive specifies valid sources for including the stylesheets- may it be externally loaded stylesheets or inline use of the HTML style attributes. The Stylesheets, which belong to different source apart from that, are not included in the source list are not requested or loaded.
Content – Security – Policy: style-src directive value;
Example: Content – Security – Policy: style-src www.abc.com;
This would load stylesheets belonging to only abc.com domain. It will not even load the html style attributes specified using style element in the page. In order to include the inline style while using the style-src directive, one has to specify explicitly the ‘unsafe-inline’ value also to the style-src directive as below –
Content-Security-Policy: style-src ‘unsafe-inline’, www.test.com;
This directive is used to restrict a page’s actions like preventing popups, execution of plugins and scripts, and enforcing a same-origin policy.
Grammar: Content-Security- Policy: sandbox value;
If the value isn’t specifies then the default value would be “is sandbox allow-scripts allow-forms”.
Default-src: This is a default directive and in case any directive not set, then the value of the default-src directive is considered as the value for the unset directive. Thus, this default-src defines loading policy for all the resource types when a resource type dedicated directive is not defined (fallback). This rule applies to the below mentioned directive-child-src
Grammar: Content-security-Policy: default-src value
Example: Content-security-Policy: default-src ‘self’;
This would be interpreted by the browser as all the loading of scripts, images, media, frame content, objects, style sheets, connections are to be done only with the same domain as that of the page.
When the directive for a specified resource is not defined and a default-src is defined, then the default-src value is considered to be the value of the undefined directive.
When both default-src and the specific resource type directive are defined, then the specific resource type directive value is considered.
Example: Content – security – Policy: script-src ‘self’; default-src ‘self ‘,www.test.com;
If it is specified as above, the scripts are loaded only from the same domain as the script-src is specified and all other resources will be loaded from same and as well as test.com domain as the default-src is defined for the undefined directivez.
Content –security-policy is one of a great policies when used correctly. The risk with CSP is improper configuration and too permissive policies. So, one has to thoroughly test the application once the CSP directives are implemented and only then go for production. CSP not only provides an ability for web applications to specify what type and from where content can be loaded, but also provides some protection from cross-site scripting and other data injection attacks. However, one should not completely rely on CSP to provide cent percent security; it can be used only as an early warning mechanism for attacks that appear in the wild. Though it is not widely adopted by a majority of the web browser market, CSP can prove a useful layer in protecting web applications and their users.