Every HTTP response is a conversation. Most people only read the body — but the headers tell you everything about how a server is configured, what it's protecting, and where it's vulnerable.

Why HTTP Headers Matter in Security

After mapping open ports with Nmap, the next layer of reconnaissance is understanding what those services communicate when you talk to them. Every web server responds to requests with a set of HTTP headers — metadata that travels alongside the content. These headers control browser behavior, cache policies, cookie settings, and critically, security policies.

From an attacker's perspective, headers reveal misconfigurations and missing protections. From a defender's perspective, they're one of the first things a security audit checks. From a penetration tester's perspective, they're the starting point for understanding what the application is trying to protect — and whether it's succeeding.

In this lab I intercepted and analyzed the HTTP response headers from a live web server, then explored how OWASP ZAP automates this kind of analysis at scale.

The Lab — Capturing an HTTP Response

The target for this exercise was ciccc.ca — a real-world website analyzed as part of a controlled classroom exercise. Using a proxy tool to intercept the response, I captured the full set of HTTP headers returned by the server.

The response started with:

HTTP/1.1 200 OK

A 200 OK means the server is reachable and the request succeeded. That's the baseline — now the interesting part begins.

Breaking Down the Headers — All 16

1. HTTP/1.1 200 OK

The status line. 200 means success. Other codes you'd watch for in a security context: 301/302 (redirects — potential open redirect vulnerabilities), 403 (forbidden — something exists but is blocked), 500 (server error — may indicate unhandled exceptions leaking stack traces).

2. Alt-Svc: h3=":443"; ma=2592000

Advertises support for HTTP/3 (QUIC protocol) on port 443. Not a security concern on its own, but tells you the server is modern and running a CDN or edge service.

3. Cache-Control: public, s-maxage=60, stale-while-revalidate=300

Defines caching behavior. public means the response can be cached by proxies and CDNs. From a security standpoint, sensitive pages (dashboards, account pages) should use Cache-Control: no-store — caching authenticated responses can expose user data through shared caches.

4. Content-Type: text/html; charset=utf-8

Declares the content type and character encoding. Missing or incorrect Content-Type is a classic XSS enabler — browsers used to "sniff" the content type and execute unexpected content as scripts. That's exactly what header 13 (X-Content-Type-Options: nosniff) is designed to prevent.

5. Date: Fri, 27 Mar 2026 01:29:42 GMT

Server timestamp. Useful for confirming the server's timezone and clock — discrepancies between server time and log timestamps can complicate incident response.

6 & 7. Link headers — alternate languages and preloaded assets

These reveal the site's internationalization setup (English, Spanish, French, Korean, Portuguese) and which CSS/font files are preloaded. For a penetration tester, Link headers can expose internal file paths and asset structure that aren't visible in the HTML source.

8. Permissions-Policy

Controls which browser APIs the page can access. This server explicitly restricts camera, geolocation, payment, USB, accelerometer, and gyroscope — but grants microphone and clipboard access to app.dante-ai.com. That third-party domain having clipboard access is worth noting: it means a script from that domain can read and write the user's clipboard.

9. Referrer-Policy: strict-origin-when-cross-origin

Controls how much URL information is included in the Referer header when navigating between pages. strict-origin-when-cross-origin means full URLs are only sent for same-origin requests — external sites only see the origin, not the full path. This prevents leaking sensitive URL parameters (tokens, session IDs) to third-party analytics or ad networks.

10. Set-Cookie: NEXT_LOCALE=en; Path=/; SameSite=lax

Sets a cookie for language preference. The SameSite=lax attribute is a CSRF mitigation — it prevents the cookie from being sent on cross-site POST requests. What's missing here: the Secure flag (which would restrict the cookie to HTTPS only) and HttpOnly (which would prevent JavaScript from reading it). For a session cookie, both would be required.

The Four Security Headers That Actually Matter

Headers 11, 13, 14, and 15 are the ones every security assessment checks. Missing any of these is a finding.

11. Strict-Transport-Security: max-age=31536000; includeSubDomains 🔒

HSTS tells the browser to never connect to this domain over plain HTTP — all future requests are automatically upgraded to HTTPS, and certificate errors cannot be bypassed by the user. max-age=31536000 means this policy is cached for one year. includeSubDomains extends it to every subdomain.

Without HSTS, an attacker performing a man-in-the-middle attack can intercept an initial HTTP request before the redirect to HTTPS fires — the classic SSL stripping attack. HSTS closes that window entirely.

13. X-Content-Type-Options: nosniff 🔒

Prevents browsers from guessing (sniffing) the content type of a response. Without this header, a browser might execute a file served as text/plain as JavaScript if it detects script-like content — enabling MIME confusion attacks and XSS. nosniff enforces strict type checking.

14. X-Frame-Options: SAMEORIGIN 🔒

Controls whether the page can be embedded inside a <frame> or <iframe>. SAMEORIGIN means only pages from the same origin can embed it — external sites cannot. Without this, the site would be vulnerable to clickjacking: an attacker overlays a transparent iframe of the target site over a fake page, tricking users into clicking buttons they can't see.

15. X-XSS-Protection: 1; mode=block 🔒

Activates the browser's built-in XSS filter. mode=block means if a reflected XSS attack is detected, the browser blocks the entire page rather than sanitizing and rendering it. Note: modern browsers have deprecated this header in favor of Content-Security-Policy, but it remains valuable for older browser compatibility.

Security Header Summary

Header Present Protection Strict-Transport-Security ✅ SSL stripping, MITM X-Content-Type-Options ✅ MIME sniffing, XSS X-Frame-Options ✅ Clickjacking X-XSS-Protection ✅ Reflected XSS Content-Security-Policy ❌ XSS, injection (not present) Permissions-Policy ✅ Browser API abuse Referrer-Policy ✅ Information leakage

The notable absence here is Content-Security-Policy (CSP) — the modern, fine-grained replacement for X-XSS-Protection. CSP allows servers to whitelist exactly which scripts, styles, and resources a page is allowed to load, blocking inline script injection at the browser level. Its absence would be a finding in a formal web application assessment.

OWASP ZAP — Automating HTTP Analysis at Scale

Manually reading headers is useful for learning. In practice, security assessments use automated tools to scan entire applications. OWASP ZAP (Zed Attack Proxy) is the open-source standard for this — a free, actively maintained web application security scanner backed by OWASP.

How ZAP works

ZAP operates as a man-in-the-middle proxy sitting between your browser and the target web application. All traffic passes through it, giving ZAP complete visibility into every request and response.

Browser  →  ZAP Proxy (localhost:8080)  →  Target Web Server
Browser  ←  ZAP Proxy (intercept/log)  ←  Target Web Server

The four phases of a ZAP scan

Proxy Interception — ZAP captures every HTTP request and response as you browse normally. You can inspect, modify, and replay any message. This is how a tester would manually test input fields, modify cookies, or tamper with form parameters.

Spidering (Crawling) — ZAP maps the application's structure automatically. The traditional spider parses HTML links. The AJAX spider executes JavaScript to discover pages that only appear after user interaction — essential for modern single-page applications (SPAs) built with React, Vue, or Angular.

Passive Scan — ZAP analyzes all captured traffic for vulnerabilities without sending any additional requests. Since it only observes, it's safe to run against live production sites. This is where missing security headers, insecure cookies, and information disclosure issues surface.

Active Scan — ZAP actively attacks the application by sending crafted payloads: SQL injection strings, XSS payloads, path traversal sequences, and more. This generates real attack traffic and should only be run against systems you have written authorization to test.

ZAP automation capabilities

Beyond manual testing, ZAP integrates directly into CI/CD pipelines:

  • Baseline Scan — runs passive scan only, safe for automated testing against staging environments. Fails the build if high-severity issues are found.
  • Full Scan — runs spidering + active scanning, used in dedicated security testing stages.
  • API Scanning — supports REST and GraphQL API scanning using OpenAPI/Swagger definitions, which is increasingly important as applications move toward API-first architectures.

This CI/CD integration is what makes ZAP relevant to DevSecOps roles — it's not just a manual testing tool, it's a security gate in the development pipeline.

The Connection to Nmap

After the last two labs mapping open ports and enumerating services with Nmap, this exercise fills in the next layer: what do those services say when you actually talk to them?

The progression looks like this:

Nmap scan          →  Port 80 open, Apache 2.2.8
                            ↓
HTTP header analysis  →  What security policies does the server enforce?
                            ↓
OWASP ZAP             →  What vulnerabilities exist in the application itself?

Each layer builds on the previous one. A port scanner tells you the door is open. HTTP headers tell you what locks are on it. A web application scanner tells you whether those locks actually work.

What This Lab Taught Me

HTTP headers are a server's security posture in plain text. In under a second, a single response tells you whether a server enforces HTTPS, prevents clickjacking, blocks MIME sniffing, and restricts iframe embedding. A well-configured server has all four. A misconfigured one is missing one or more — and each gap is a documented attack vector.

The gap between "present" and "correct" matters. Set-Cookie was present but missing Secure and HttpOnly. X-XSS-Protection was present but is deprecated in favor of CSP, which was absent. Security headers aren't checkbox items — each one has specific attributes that determine whether it actually provides protection.

ZAP bridges manual analysis and automated testing. Understanding headers manually first makes ZAP's output meaningful — you know why a missing Content-Security-Policy is flagged as high severity, not just that it is. That context is what separates someone who runs tools from someone who interprets results.

What's Next

With reconnaissance wrapped up — ports, services, headers, and web application scanning — the series moves into traffic analysis. The next articles use Wireshark to analyze packet captures from real attack scenarios: malware delivery chains, lateral movement via PsExec, and a full Tomcat compromise from port scan to reverse shell.

This article is part of my cybersecurity portfolio series documenting hands-on learning across red team and blue team disciplines.

Tags: Cybersecurity Web Security HTTP OWASP Penetration Testing Ethical Hacking Network Security