Skip to content
CYBERLENS / LOOK BENEATH THE SURFACE
← THE JOURNAL / Scripts & applications

Build your first security project: a local-only header inspector.

Run a tiny Python web server on loopback and inspect its response headers. A complete beginner project with a visible before-and-after result.

CyberLens Lab•Site publication: 22 Oct 2026•6 min read

The project and the boundary

Build a small page, inspect its response and explain which controls are present. This server binds only to 127.0.0.1 on your own computer. It is a local teaching example, not a production server or a tool for scanning third-party sites.

You need Python 3 and an unused local port 8088. Save the following as header_lab.py.

from http.server import BaseHTTPRequestHandler, HTTPServer

class Lesson(BaseHTTPRequestHandler):
    def do_GET(self):
        body = b"<h1>CyberLens local lab</h1><p>Dummy content only.</p>"
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        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(body)

HTTPServer(("127.0.0.1", 8088), Lesson).serve_forever()

Run and observe

Run python3 header_lab.py. Open http://127.0.0.1:8088/ on that same computer, then inspect the response headers in the browser’s Network panel. Alternatively, in another terminal run:

curl -i http://127.0.0.1:8088/

Expected result: an HTTP 200 response containing the two explicit security headers and the dummy page. In Windows PowerShell, use curl.exe -i http://127.0.0.1:8088/ to select the curl executable if an alias behaves differently. Stop the server with Ctrl+C.

Make the comparison visible

For an initial “before” recording, omit only the two send_header calls for the security controls, restart and inspect again. Restore those lines, restart and compare the response. Keep the server on loopback throughout.

nosniff asks a browser to respect the declared content type. This restrictive Content Security Policy blocks resource loads and embedding for this tiny page. Neither header supplies authentication, patches a vulnerable dependency or encrypts HTTP traffic. HSTS is intentionally absent because this example does not serve HTTPS.

Turn a toy into a portfolio lesson

Include the scope, expected output, screenshots, explanation, limits and clean shutdown in your recording. A useful project shows what was tested and why a control changed the result. It does not need fabricated attack footage or claims that a single header stops all hacking.

References: Python http.server documentation and W3C Content Security Policy. Python’s built-in server is not recommended for production. Source checked: 22 October 2026.