bhylu.com

Advertisements

Cybersecurity HTTP Security Headers

Check an actual response from an owned local HTTP fixture.

How it works

Response headers can constrain how browsers load or expose content. A Content Security Policy should be designed for the page’s resources; a copied policy can break the site or leave unnecessary permissions. nosniff prevents some MIME-type guessing. This fixture verifies two response headers over loopback; its plain HTTP transport is a local demonstration, not a production HTTPS setup.

Run the code

Save the complete source as http-security-headers.py in a separate learning folder, then run python http-security-headers.py. The reviewed runtime is Python 3.12.14 with the standard library; no third-party packages are required. These are local examples, not browser playground programs. Apache, MySQL and PHP are not needed.

Download the complete source

Local lab setup

Example

http-security-headers.py

from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from urllib.request import urlopen
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("X-Content-Type-Options", "nosniff")
        self.send_header("Content-Security-Policy", "default-src 'none'; frame-ancestors 'none'")
        self.end_headers()
        self.wfile.write(b"fixture")
    def log_message(self, *args):
        pass
server = HTTPServer(("127.0.0.1", 0), Handler)
thread = Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
    with urlopen(f"http://127.0.0.1:{server.server_port}/", timeout=3) as response:
        assert response.read() == b"fixture"
        assert response.headers["X-Content-Type-Options"] == "nosniff"
        assert "frame-ancestors 'none'" in response.headers["Content-Security-Policy"]
    print("loopback response headers verified")
finally:
    server.shutdown()
    server.server_close()
    thread.join(timeout=3)

Expected result

loopback response headers verified

The handler binds only to 127.0.0.1 and receives an operating-system allocated port. The client checks the delivered headers rather than a configuration dictionary. The finally block shuts the server down even if an assertion fails. Browser enforcement, a real proxy chain and TLS require separate integration testing.

Technical reference: OWASP Cheat Sheet Series. Check the guidance for your actual platform and deployment.