Understanding Content Security Policy (CSP): In-Depth Guide to Directives and Secure Practices

In today’s digital landscape, ensuring the security of web applications is paramount. One of the most effective measures to enhance web security is implementing a Content Security Policy (CSP). This article delves into CSP, explaining key directives like unsafe-eval, unsafe-inline, blob, and data:, and providing comprehensive implementation details in HTML, Nginx, and PHP.

What is Content Security Policy (CSP)?

Content Security Policy (CSP) is a security standard that helps prevent various types of attacks, such as Cross-Site Scripting (XSS) and data injection attacks. CSP allows web developers to specify trusted sources for content loaded on their web pages, thereby mitigating the risk of executing malicious scripts.

Key CSP Directives

CSP directives are used to control the sources from which various types of content can be loaded. Below is a list of key CSP directives:

  1. default-src: Defines the default policy for fetching resources such as scripts, styles, images, etc.
  2. script-src: Specifies the sources for JavaScript.
  3. style-src: Specifies the sources for CSS.
  4. img-src: Specifies the sources for images.
  5. connect-src: Specifies the sources for XMLHttpRequest (AJAX), WebSocket connections, and EventSource.
  6. font-src: Specifies the sources for fonts.
  7. object-src: Specifies the sources for plugins like Flash.
  8. media-src: Specifies the sources for media files like audio and video.
  9. frame-src: Specifies the sources for embedded frames.
  10. sandbox: Applies restrictions to the content within the element or document.
  11. report-uri: Specifies the URI to which the browser sends reports about policy violations.
  12. base-uri: Restricts the URLs which can be used in a document’s <base> element.
  13. form-action: Restricts the URLs which can be used as action targets of forms.
  14. child-src: Specifies the sources for web workers and nested browsing contexts such as iframes.
  15. frame-ancestors: Specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>.
  16. worker-src: Specifies the sources for worker scripts.
  17. manifest-src: Specifies the sources for web app manifests.
  18. prefetch-src: Specifies the sources for link prefetching.
  19. upgrade-insecure-requests: Instructs browsers to treat all HTTP requests as HTTPS.
  20. block-all-mixed-content: Prevents loading any assets using HTTP when the page is loaded using HTTPS.

Special Directives

unsafe-eval

The unsafe-eval directive allows the use of JavaScript’s eval() function and similar methods like setTimeout(string), setInterval(string), and new Function(string). These methods execute strings of code dynamically, which can be exploited by attackers to run malicious scripts.

Example:

Content-Security-Policy: script-src 'self' 'unsafe-eval';

Security Implications:
Using unsafe-eval is discouraged because it makes the application vulnerable to XSS attacks. It’s best to refactor code to avoid using eval() and similar functions.

unsafe-inline

The unsafe-inline directive allows the execution of inline JavaScript and CSS, including scripts and styles directly within HTML documents.

Example:

Content-Security-Policy: script-src 'self' 'unsafe-inline';
JavaScript

Security Implications:
Using unsafe-inline significantly reduces the security of CSP. Instead of using unsafe-inline, consider using nonces or hashes to allow specific inline scripts and styles.

blob

The blob: directive allows loading resources from blob: URLs. Blob URLs are used to represent Blob objects and File objects. They are often used to reference data that can be created dynamically within the web application.

Example:

Content-Security-Policy: default-src 'self' blob:;
JavaScript

Security Implications:
Allowing blob: URLs can be safe when used correctly but ensure that blobs are not created from untrusted sources to prevent security risks.

data:

The data: directive allows resources to be loaded from data: URLs. Data URLs are used to embed small files inline in web pages, such as images or other media.

Example:

Content-Security-Policy: img-src 'self' data:;
JavaScript

Security Implications:
Using data: URLs can introduce security risks, especially if combined with other unsafe sources. Limit its use to necessary and trusted content only.

Implementing CSP in HTML

CSP can be implemented in HTML using the <meta> tag, suitable for static websites or specifying CSP directly within the HTML file.

Example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example CSP</title>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline';">
</head>
<body>
    <h1>Content Security Policy Example</h1>
    <script src="https://trusted.cdn.com/example.js"></script>
    <style>
        body { background-color: lightgrey; }
    </style>
</body>
</html>
HTML

Configuring CSP on the Server Side

For dynamic websites or when managing many pages, configuring CSP on the server side is more practical. Below are examples for configuring CSP in Nginx and PHP.

Nginx Configuration

To configure CSP in Nginx, add the CSP header in your Nginx configuration file.

Example:

server {
    listen 80;
    server_name example.com;

    location / {
        add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline';";
        # Other configurations...
    }
}
Nginx

Reload Nginx to apply the changes:

sudo systemctl reload nginx

PHP Configuration

To configure CSP in PHP, use the header() function to send the CSP header.

Example:

<?php
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline';");
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example CSP</title>
</head>
<body>
    <h1>Content Security Policy Example</h1>
    <script src="https://trusted.cdn.com/example.js"></script>
    <style>
        body { background-color: lightgrey; }
    </style>
</body>
</html>
PHP

Example Codes and Policies

Example 1: Basic CSP Policy

This policy allows content only from the same origin:

Content-Security-Policy: default-src 'self';

Example 2: Allowing Scripts from a Trusted Source

This policy allows scripts from the same origin and a trusted CDN:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;

Example 3: Using Nonces for Inline Scripts

This policy uses a nonce to allow specific inline scripts:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-<random-value>';

In your HTML, add the nonce to the script tag:

<script nonce="<random-value>">
    // Your inline script here
</script>

Example 4: Reporting Violations

This policy specifies a URI to report CSP violations:

Content-Security-Policy: default-src 'self'; report-uri /csp-violation-report-endpoint;

Conclusion

Implementing Content Security Policy (CSP) is a vital step towards securing web applications against various types of attacks. Understanding and properly configuring directives like unsafe-eval, unsafe-inline, blob, and data: is crucial for maintaining a robust security posture. Whether through HTML meta tags or server-side configurations in Nginx and PHP, CSP helps define and enforce trusted sources for web content. By following best practices and tailoring CSP policies to your web application’s needs, you can significantly enhance its security and protect your users.

Leave a Reply

Your email address will not be published. Required fields are marked *