4 Min

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 domain https://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. via fetch or XHR) 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

  1. Protection against XSS attacks: CSP prevents malicious JavaScript from being executed on the page from unauthorized sources.

  2. Prevents data leaks: CSP can prevent sensitive data from being transmitted to external servers by malicious scripts.

  3. 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

  1. default-src 'self';: By default, resources (e.g. scripts, images, styles) may only be loaded from your own domain.

  2. script-src 'self' https://trusted-scripts.com;: Scripts may only be loaded from your own domain and from https://trusted-scripts.com. This protects against XSS, as scripts from other sources are blocked.

  3. style-src 'self' https://fonts.googleapis.com 'unsafe-inline';: CSS may be loaded from your own domain and from https://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.

  4. img-src 'self' data: https://trusted-images.com;: Images may be loaded from your own domain, from data: URLs (e.g. Base64-encoded images) and from https://trusted-images.com.

  5. font-src 'self' https://fonts.gstatic.com;: Fonts may be loaded from your own domain and from https://fonts.gstatic.com.

  6. connect-src 'self' https://api.trusted.com;: Network connections (e.g. for AJAX requests) may only be made to your own domain and to https://api.trusted.com.

  7. frame-src 'none';: Embedding content in <iframe> elements is not allowed to prevent clickjacking attacks.

  8. object-src 'none';: Loading of plugins or embedded objects is completely blocked.

  9. base-uri 'self';: Setting the base URI for relative URLs is restricted to the own domain.

  10. form-action 'self';: Forms are only allowed to send data to the own domain.

  11. 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

  1. 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 the report-uri endpoint is active to capture violations.

  2. Monitor reports: Analyze reports to understand which resources may not be loading correctly and adjust the CSP accordingly.

  3. 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.

Updated: