Docs / Security / How to Configure Content Security Policy Headers

How to Configure Content Security Policy Headers

By Admin · Mar 2, 2026 · Updated Apr 25, 2026 · 27 views · 4 min read

How to Configure Content Security Policy Headers

Content Security Policy (CSP) is a security header that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks by controlling which resources a browser is allowed to load. Properly configuring CSP on your Breeze instance's web applications is one of the most effective client-side security measures available.

Understanding CSP Directives

CSP uses directives to control different types of resources:

  • default-src — fallback for all resource types not explicitly specified
  • script-src — controls JavaScript sources
  • style-src — controls CSS sources
  • img-src — controls image sources
  • font-src — controls web font sources
  • connect-src — controls fetch, XHR, and WebSocket connections
  • frame-src — controls iframe sources
  • object-src — controls plugins like Flash (should always be 'none')
  • base-uri — restricts the base element URL
  • form-action — restricts form submission targets
  • frame-ancestors — controls which sites can embed your page (replaces X-Frame-Options)

Basic CSP Configuration in Nginx

server {
    listen 443 ssl;
    server_name yourdomain.com;

    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;

    # ... rest of config
}

Basic CSP Configuration in Apache

<VirtualHost *:443>
    ServerName yourdomain.com

    Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';"

    # ... rest of config
</VirtualHost>

Setting CSP in PHP

You can also set CSP headers directly in your PHP application:

<?php
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';");

Using Report-Only Mode

Test your CSP without blocking resources by using Content-Security-Policy-Report-Only:

add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; report-uri /csp-report;" always;

Create an endpoint to collect violation reports:

<?php
// /csp-report.php
$data = file_get_contents('php://input');
$report = json_decode($data, true);
if ($report) {
    $logEntry = date('Y-m-d H:i:s') . ' ' . json_encode($report) . "\n";
    file_put_contents('/var/log/csp-reports.log', $logEntry, FILE_APPEND);
}
http_response_code(204);

Handling Inline Scripts and Styles

Instead of using 'unsafe-inline', use nonces or hashes for better security:

Nonce-Based Approach

<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'nonce-{$nonce}'; style-src 'nonce-{$nonce}';");
?>
<script nonce="<?= $nonce ?>">
    // This inline script is allowed because the nonce matches
    console.log('Allowed by CSP');
</script>

Hash-Based Approach

# Generate the hash of your inline script
echo -n "console.log('hello');" | openssl dgst -sha256 -binary | openssl enc -base64

# Use the hash in your CSP header
Content-Security-Policy: script-src 'sha256-AbCdEf123...=';

Complete Production CSP Example

A real-world CSP for a web application on your Breeze instance:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{random}' https://cdn.jsdelivr.net;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  img-src 'self' data: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.yourdomain.com wss://yourdomain.com;
  media-src 'self';
  object-src 'none';
  child-src 'self';
  frame-ancestors 'self';
  base-uri 'self';
  form-action 'self';
  upgrade-insecure-requests;

Additional Security Headers

CSP works best alongside other security headers:

# Prevent MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Enable XSS filter
add_header X-XSS-Protection "1; mode=block" always;

# Control referrer information
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Restrict browser features
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

# Force HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Best Practices

  • Start with report-only mode — deploy CSP in report-only first to identify what will break
  • Avoid unsafe-inline and unsafe-eval — use nonces or hashes instead for inline code
  • Be as restrictive as possible — only allow the sources your application actually needs
  • Monitor violation reports — review reports to detect both policy issues and potential attacks
  • Update policies when adding third-party resources — each new CDN or API endpoint needs explicit allowlisting

A well-configured Content Security Policy is a powerful defense against XSS and injection attacks on web applications running on your Breeze instance, significantly reducing the risk of client-side exploitation.

Was this article helpful?