Implementing a Secure Content Security Policy (CSP)

Search for a command to run...

No comments yet. Be the first to comment.
AngularJS sandbox escape
![[EXPERT] Reflected XSS with AngularJS sandbox escape without strings](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fuploads%2Fcovers%2F66f6453769132feb8ba076b0%2F111ea636-bcfe-491b-b495-b6549d0ebcfe.png&w=3840&q=75)
BreachForce June 2026 Meetup Highlights

HackTheBox Mumbai - May Meetup

BreachForce Meetup May - Security Automation and Malware Research

Disclaimer ⚠️ Where the Scheduler whispers, processes tremble — for it decides who runs… and who fades into starvation. The following content ventures into the ticking heart of the OS — where time slices are bargained, queues grow restless, and sched...
![Lecture 4 - Rediscovering Process Scheduling [Part - 1]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1765604682888%2F80e6cf20-aded-4aac-8c75-affdd35615b2.jpeg&w=3840&q=75)
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 a CSP header employs the hardened security framework of the modern browser, baking it into the end users' web application.
However,
the resilience of CSP headers are often compromised during web development due to numerous gaps introduced by developers to support certain libraries/inline scripts/quick integrations etc. Additionally if Content Security Policy (CSP) header is not implemented it can be a major red flag.
Example of an insecure Content Security Policy (CSP)
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>:If Content Security Policy (CSP) header is not set - implement it immediately. The 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.
Example of a Secure Content Security Policy (CSP)
Content-Security-Policy: default-src 'self’;
frame-src 'self';
script-src 'self' https://cdn.jsdelivr.net/npm/@floating-ui/core@1.2.1;
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.
<meta> tag, the directive is ignored.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. Example Report-To header
Report-To: {"group":"csp-error","max_age":180000,"endpoints":[{"url":"https://sumirbroota.com/csp-violations"}],"include_subdomains":true}
For Apache:
Header always set Content-Security-Policy "default-src 'self';"
in your /etc/apache2/sites-enabled/example.conf file.
For Nginx:
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 & Google CSP Evaluator to create a Content-Security-Policy for a website based on the statically detectable relations. Note you will still have to validate it yourself
TLDRContent Security Policy (CSP) provides a mechanism 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:
- Be cautious of 3rd party urls & using '*' in even in trusted urls, if a direct url can be used, it would be best.
- Do not use 'unsafe-eval'/'unsafe-inline' instead use a nonce or a hash value.
- default-src directive defines the default policy for fetching resources hence make sure it is airtight.
- 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
- Avoid using the 'data' scheme as it can be used as a vector for XSS.