๐ Content Security Policies
Policies that provide security
A Content-Security Policy (CSP) is a security measure supported by modern web browsers to prevent attacks on web pages, particularly Cross-Site Scripting (XSS) and Code Injection attacks. CSP helps developers control which resources (such as scripts, images, styles, etc.) can be loaded and executed by a website.
How does CSP work?
CSP is implemented through HTTP headers. The website sends a policy to the browser that specifies what types of content can be loaded and executed from which sources. If the browser finds a resource or code that does not match the policy, it blocks it.
Simple example rule of a CSP
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-scripts.com; object-src 'none'
This rule specifies several things:
default-src 'self'
: By default, all resources (e.g. images, videos) may only be loaded from the own domain ('self'
).script-src 'self' https://trusted-scripts.com
: Scripts may only be loaded from the own domain ('self'
) or the trusted domainhttps://trusted-scripts.com
.object-src 'none'
: Prevents loading of plugins or embedded objects (e.g. Flash or Java applets), as these often serve as entry points for attacks.
Commonly used directives
default-src
: Determines the default source for all types of resources (if more specific directives are missing).script-src
: Specifies where JavaScript code may be loaded and executed from.style-src
: Determines where CSS may be loaded from.img-src
: Defines where images may be loaded from.font-src
: Specifies where fonts may be loaded from.object-src
: Controls where embedded content such as<object>
,<embed>
, or<applet>
may be loaded from.connect-src
: Controls where network requests (e.g. viafetch
orXHR
) may be sent.frame-src
: Specifies where content in<iframe>
may be loaded from.report-uri
: Specifies a URL to which the browser can report CSP violations.
Benefits of CSP
-
Protection against XSS attacks: CSP prevents malicious JavaScript from being executed on the page from unauthorized sources.
-
Prevents data leaks: CSP can prevent sensitive data from being transmitted to external servers by malicious scripts.
-
Protection against code injection: It prevents attackers from loading malicious scripts or content from unsafe sources.
Example: Protection against XSS attacks
For example, a classic XSS attack could inject a malicious script onto a website that steals user data. With a properly configured CSP, the browser could block the execution of this script if it comes from an unauthorized source.
Phased implementation
A common practice is to first test CSP in โreport-onlyโ mode to monitor which resources would be blocked without actually blocking them. This can help identify issues before the policy is strictly applied.
Example of a report-only policy:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint
This sends violations to the specified reporting URL without actually blocking resources.
A solid Content Security Policy (CSP) configuration for small to medium-sized websites can help significantly reduce the risk of vulnerabilities such as Cross-Site Scripting (XSS) and Code Injection attacks.
Here is an example of a CSP that can be implemented in an HTML document to ensure balanced security.
Example of a solid CSP configuration
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example of Content Security Policy</title>
<meta http-equiv="Content-Security-Policy" content=" default-src 'self'; rc 'self' https://trusted-scripts.com; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data: https://trusted-images.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.trusted.com;
frame-src 'none';
object-src 'none';
base-uri 'self';
form-action 'self';
report-uri /csp-report-endpoint;
">
<!-- Example CSS from an allowed source -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
<script src="https://trusted-scripts.com/script.js" defer></script>
</head>
<body>
<h1>Welcome to my website</h1>
<img src="https://trusted-images.com/image.jpg" alt="Example image">
<form action="/submit" method="POST">
<input type="text" name="username" required>
<button type="submit">Submit</button>
</form>
<script>
// Inline scripts are not allowed, so we use external scripts
console.log('Hello, World!');
</script>
</body>
</html>
Explanation of the CSP directives
-
default-src 'self';
: By default, resources (e.g. scripts, images, styles) may only be loaded from your own domain. -
script-src 'self' https://trusted-scripts.com;
: Scripts may only be loaded from your own domain and fromhttps://trusted-scripts.com
. This protects against XSS, as scripts from other sources are blocked. -
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
: CSS may be loaded from your own domain and fromhttps://fonts.googleapis.com
. Adding'unsafe-inline'
enables the use of inline styles, but should be used with caution as this can pose a security risk. -
img-src 'self' data: https://trusted-images.com;
: Images may be loaded from your own domain, fromdata:
URLs (e.g. Base64-encoded images) and fromhttps://trusted-images.com
. -
font-src 'self' https://fonts.gstatic.com;
: Fonts may be loaded from your own domain and fromhttps://fonts.gstatic.com
. -
connect-src 'self' https://api.trusted.com;
: Network connections (e.g. for AJAX requests) may only be made to your own domain and tohttps://api.trusted.com
. -
frame-src 'none';
: Embedding content in<iframe>
elements is not allowed to prevent clickjacking attacks. -
object-src 'none';
: Loading of plugins or embedded objects is completely blocked. -
base-uri 'self';
: Setting the base URI for relative URLs is restricted to the own domain. -
form-action 'self';
: Forms are only allowed to send data to the own domain. -
report-uri /csp-report-endpoint;
: Reports of CSP violations are sent to the specified endpoint. This helps identify problems without immediately blocking the policy.
Implementation and testing
-
Testing the CSP: Start with a report-only policy to see what resources would be blocked without actually blocking them. Change the meta to
Content-Security-Policy-Report-Only
and make sure thereport-uri
endpoint is active to capture violations. -
Monitor reports: Analyze reports to understand which resources may not be loading correctly and adjust the CSP accordingly.
-
Iterative improvement: Regularly optimize the CSP to account for new attack vectors and improve your siteโs security.
Conclusion
A solid content security policy is an important step to increase your siteโs security, but it should be reviewed and adjusted regularly to ensure it remains both secure and user-friendly.