Hacker's Blog

Search

Search IconIcon to open search

Content Security Policy (CSP)

Last updated Jul 8, 2024 Request an edit

# Skip to TLDR;?

# Introduction

Content Security Policy (CSP) provides mechanisms for websites to restrict content that browsers will be allowed to load. It is the holy grail for client side web application security. A strong policy can provide monumental protection against threats such as Cross Site Scripting (XSS), Cross-Origin Resource Sharing (CORS), Click-jacking, HTTP Downgrade attacks and much more. This is because CSP employs the hardened security framework of the modern browser, baking it into the end users’ web application.

However,

the resilience of CSP is often compromised during web development due to numerous gaps introduced by developers to support certain libraries/inline scripts/quick integrations etc.

# Learning from Common Mistakes:

1
2
3
Content-Security-Policy: default-src 'self’ <source> *; 
frame-src http://3rdparty.site <source>; 
script-src *.google.com:80 <source> cdn.js unsafe-inline unsafe-eval;

Not sure what frame-src or any other directives are ? - Click here

# Insecure default-src:

This is the policy the browser must refer to in case there is no specific one mentioned i.e the default case. Here although the scope of the default-src mentions ‘self’ (allowing only one’s own website as the scope), the presence of ‘*’ directs the browser to accept sources from anywhere. The use of such a broad scope can be very dangerous.

# Lack of font-src, img-src, connect-src, media-src & more:

These additional policies have not been mentioned hence default-src would be used. Making the job of tightening the security of default-src paramount. The above policies are used in case you wish to make an exception for a particular src such as img-src, but don’t want to weaken the security of the default/other configurations.

# Avoid ‘unsafe-eval’/‘unsafe-inline’

Using these in any directive is a HUGE risk and must be avoided. Just their mere presence introduces a vector for the execution of DOM based and inline XSS. Instead move the scripts into separate javascript files or use a nonce/hash value

# Defining your <source>:

# 1. Define strict scope even for reputed first party sites
# 2. Be sure about adding 3rd party websites to your CSP
# 3. Always think twice when adding ‘*’ to a CSP regex:

# Recommendation:

If Content Security Policy is not already present - implement it immediately. Content Security Policy can be set either in the response header or in the html’s meta tag, the prior being given a higher priority.

1
2
3
4
5
6
7
Content-Security-Policy: default-src 'self’; 
frame-src 'self'; 
script-src 'self' https://cdn.jsdelivr.net/npm/@floating-ui/[email protected];
frame-ancestors ‘none’;
report-to csp-error;
report-uri https://sumirbroota.com/csp-violations
upgrade-insecure-requests;

# frame-ancestors ‘none’:

This is a suitable setting in case one is not using an iframe in their sites functionality. frame-ancestors restricts the URLs that can embed the requested resource inside of <frame>, <iframe>, <object>, <embed>, or <applet> elements.

# upgrade-insecure-requests:

The following directive will ensure that all requests will be sent over HTTPS with no fallback to HTTP

# report-to:

Reporting directives delivers violations of prevented behaviors to specified locations. To ensure backwards compatibility report-uri is also used.

1
Report-To: {"group":"csp-error","max_age":180000,"endpoints":[{"url":"https://sumirbroota.com/csp-violations"}],"include_subdomains":true}

  1. Be cautious of 3rd party urls & using ‘*’ in even in trusted urls, if a direct url can be used, it would be best.
  2. Do not use ‘unsafe-eval’/‘unsafe-inline’ instead use a nonce or a hash value.
  3. default-src directive defines the default policy for fetching resources hence make sure it is airtight.
  4. Use other source directives if you wish to make an exception for a specific one but don’t want to weaken the security of the other/default directives
  5. Avoid using the ‘data’ scheme as it can be used as a vector for XSS.

# Language/Framework Specific Examples:

1
Header always set Content-Security-Policy "default-src 'self';"

in your /etc/apache2/sites-enabled/example.conf file.

1
add_header Content-Security-Policy: "default-src 'self’;"; always;

in your server {} block of the /etc/nginx/sites-enabled/example.conf file. Here the always; option specifies to send the CSP no matter the response code.

Use tools such as SeeSPee to create a Content-Security-Policy for a website based on the statically detectable relations. Note you will still have to validate it yourself

TLDR;

Content Security Policy (CSP) provides mechanisms to websites to restrict content that browsers will be allowed to load e.g. inline scripts, remote javascript files. CSP can be set either in the response header or in the html’s meta tag, the prior being given a higher priority.

Recommendation:

  1. Be cautious of 3rd party urls & using ‘*’ in even in trusted urls, if a direct url can be used, it would be best.
  2. Do not use ‘unsafe-eval’/‘unsafe-inline’ instead use a nonce or a hash value.
  3. default-src directive defines the default policy for fetching resources hence make sure it is airtight.
  4. Use other source directives if you wish to make an exception for a specific one but don’t want to weaken the security of the other/default directives
  5. Avoid using the ‘data’ scheme as it can be used as a vector for XSS.

# References:

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
  2. https://www.invicti.com/web-vulnerability-scanner/vulnerabilities/content-security-policy-csp-not-implemented/
  3. https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html
  4. https://content-security-policy.com/examples/nginx/
  5. https://webdock.io/en/docs/how-guides/security-guides/how-to-configure-security-headers-in-nginx-and-apache