How to Mock a Content Security Policy Header in Python

Mock a Content-Security-Policy header locally and verify it's served correctly using Python's built-in HTTP server.

Easy Python 3.9+ Aug 9, 2026 Auth & security at scale 15 views 0 copies

Python code

36 lines
Python 3.9+
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

CSP_HEADER = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"

class MockServer(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == "/":
            self.send_response(200)
            self.send_header("Content-Type", "text/html")
            self.send_header("Content-Security-Policy", CSP_HEADER)
            self.end_headers()
            self.wfile.write(b"<html><body><h1>Mock Page</h1></body></html>")
        else:
            self.send_response(404)
            self.end_headers()

    def log_message(self, format, *args):
        pass

if __name__ == "__main__":
    server = HTTPServer(("localhost", 8000), MockServer)
    headers = {
        "Content-Security-Policy": CSP_HEADER
    }
    print("Mock server starting on port 8000")
    print(f"CSP header being served: {headers['Content-Security-Policy']}")
    print("Startup verification: sending test request...")
    
    import urllib.request
    with urllib.request.urlopen("http://localhost:8000/") as response:
        received_header = response.headers.get("Content-Security-Policy")
        print(f"Received CSP header: {received_header}")
        print(f"CSP header match: {received_header == CSP_HEADER}")
    
    server.shutdown()  # Clean shutdown after verification

Output

stdout
Mock server starting on port 8000
CSP header being served: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'
Startup verification: sending test request...
Received CSP header: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'
CSP header match: True

How it works

The BaseHTTPRequestHandler handles incoming GET requests by sending the CSP header in do_GET. Using the standard library's http.server, we build a lightweight mock that doesn't require external dependencies. The send_header method adds the Content-Security-Policy header to the response. A urllib.request request is made during startup to verify the header is served correctly. log_message is overridden to suppress default logging, keeping output clean.

This pattern lets you test browser behavior against CSP policies in local development or CI without a full server stack.

Common mistakes

  • Sending the CSP header after `end_headers()` — must be called before it
  • Forgetting to set `Content-Type` header alongside CSP for valid HTML responses
  • Hardcoding mismatched CSP values between test and production configs

Variations

  1. Use Flask's `@app.after_request` to add the header to every response in a dev app
  2. Read the CSP policy from an environment variable or config file instead of a constant

Real-world use cases

  • Testing a browser extension or SPA locally against a specific CSP policy during development.
  • Simulating a backend endpoint that serves CSP headers for integration tests in CI pipelines.
  • Debugging mixed content or inline script errors by reproducing the exact policy in a mock server.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Auth & security at scale

Related tutorials and quizzes for this topic.