Currently, I work for a major educational portal in England. Since we host numerous articles, books, and case studies, security is essential for us and, most importantly, for our customers who use the platform for research, purchasing new articles, and studying. Ensuring that our users are protected against attacks such as Cross-Site Scripting (XSS) is a top priority. To mitigate this risk, one of the most effective mechanisms is Content Security Policy (CSP), a powerful feature that we implement in our web applications.
What is Content Security Policy (CSP)?
CSP is a set of rules that restrict which resources (JavaScript, CSS, images, fonts, etc.) can be loaded on a web page. With this policy, you can prevent malicious code injection and significantly reduce the attack surface of your application.
How Does CSP Work?
CSP is defined through the HTTP header Content-Security-Policy. It specifies secure sources for scripts, stylesheets, images, and other resources.
Example of a CSP header:
Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com;
In this case, we are defining:
- default-src 'self': Allows only resources from the same domain to be loaded.
- script-src 'self' https://apis.google.com: Only local scripts and those from Google can be executed.
Content Security Policy Options
CSP allows defining rules for different types of resources:
- default-src: Defines the default source for all resource types unless specific directives are provided.
- script-src: Controls where scripts can be loaded from.
- connect-src: Defines the allowed endpoints for AJAX connections, WebSockets, and APIs like Fetch and XHR.
- style-src: Restricts the allowed stylesheets.
- font-src: Specifies where fonts can be loaded from.
- frame-src: Controls which domains can be loaded within iframes.
- img-src: Defines the allowed sources for images.
- object-src: Specifies where objects like Flash and plugins can be loaded from.
A more complete CSP header example:
Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';
Configuring CSP in Apache
If your web server is Apache, you can configure CSP by adding the following directive to the .htaccess
or httpd.conf
file:
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';"
</IfModule>
This ensures that all requests are filtered according to the defined security rules.
Configuring CSP in Nginx
If you are using Nginx, you can enable CSP by adding the following directive to your server configuration:
server {
listen 80;
server_name example.com;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://apis.google.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' https://images.example.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-src 'none'; object-src 'none';" always;
}
This configuration ensures that all resources follow the specified security rules.
Securing Your Application with CSP and JavaScript
1. Blocking Inline Scripts
CSP can block inline scripts, preventing malicious code from being injected into HTML elements. To do this, we should avoid using:
<script>alert('XSS!');</script>
And configure CSP to prevent inline scripts:
Content-Security-Policy: script-src 'self';
If you need to execute inline scripts, you can use hashes or nonces to allow only specific scripts.
2. Using Nonces to Allow Specific Scripts
A nonce (unique number per request) allows only signed scripts to be executed:
Content-Security-Policy: script-src 'nonce-random123';
In HTML:
<script nonce="random123">console.log('Allowed by CSP');</script>
3. Preventing Untrusted Resource Loading
By restricting external sources, we ensure that only trusted resources are loaded. A secure CSP might be:
Content-Security-Policy: default-src 'self'; img-src 'self' https://images.example.com; font-src 'self' https://fonts.googleapis.com;
Here, we are allowing only images and fonts from specific domains.
Monitoring and Testing CSP
To test if your application is protected, you can configure CSP in report-only mode:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report-endpoint;
This allows monitoring violations without blocking resources.
Conclusion
Implementing Content Security Policy is one of the most crucial steps in ensuring the security of modern web applications. With a well-configured CSP, you significantly reduce the risk of XSS attacks and improve protection against malicious code injections.
If you haven’t implemented CSP on your website yet, now is the time to start!
To read more about: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
Top comments (0)