HTTP Headers & Response Analysis
Use curl, Burp, and DevTools to analyze HTTP responses - security headers, cookie flags, and server banners.
↳ Based on the lesson: Ports, DNS & HTTPLegal Use Only
HTTP analysis and web application testing must only be performed on applications you own or have explicit written authorization to test. Running these techniques against production websites without authorization is illegal. This lab uses intentionally vulnerable applications (DVWA, Juice Shop) on your own VM.
Scenario
You've identified a web server during network recon. Before you test for vulnerabilities, you need to read everything the server is already telling you - in its response headers, cookies, error pages, and HTTP metadata. This passive analysis phase shapes every test that follows.
Setup - choose one:
# Option A: DVWA (Damn Vulnerable Web Application) via Docker
$ docker run -d -p 8080:80 vulnerables/web-dvwa
# Access at http://localhost:8080 (default creds: admin/password)
# Option B: OWASP Juice Shop
$ docker run -d -p 3000:3000 bkimminich/juice-shop
# Access at http://localhost:3000
# Option C: Any vulnerable Metasploitable VM on your host-only networkYour Objective
- Enumerate the web server software and version from response headers
- Identify missing or misconfigured security headers
- Analyse session cookie flags for security issues
- Map the HTTP methods the server accepts
- Find any information disclosure in error responses
Hints
curl is your best friend for raw headers
curl -I sends a HEAD request and prints only the response headers. curl -v prints full request and response including all headers. -k skips TLS cert verification for local lab targets.
Security headers checklist
The key security headers to check for: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security (HSTS), Referrer-Policy, and Permissions-Policy. Absence of any of these is a finding.
Cookie flags to check
In the Set-Cookie response header, look for: HttpOnly (blocks JS access), Secure (HTTPS-only), SameSite (CSRF protection). Missing flags are vulnerabilities, not just warnings.
Walkthrough
Step 1: Server banner and version from headers
$ curl -I http://localhost:8080/
HTTP/1.1 200 OK
Date: Mon, 26 May 2025 10:00:00 GMT
Server: Apache/2.2.8 (Ubuntu) DAV/2
X-Powered-By: PHP/5.2.4-2ubuntu5.10
Content-Type: text/html
Immediately we learn:
- Apache 2.2.8 - released 2008. This version has numerous known CVEs.
searchsploit apache 2.2.8will return results. - PHP/5.2.4 - end-of-life since 2011. Again:
searchsploit php 5.2. - Ubuntu - distribution and approximate vintage from the package version suffix.
This is information the server volunteers without any authentication or probing.
Step 2: Full response headers and security header audit
$ curl -v http://localhost:8080/ 2>&1 | grep -E "^[<>]"
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.88.1
>
< HTTP/1.1 200 OK
< Server: Apache/2.2.8 (Ubuntu) DAV/2
< X-Powered-By: PHP/5.2.4-2ubuntu5.10
< Set-Cookie: PHPSESSID=abc123; path=/
< Content-Type: text/htmlSecurity header audit - what's missing:
| Header | Present? | Issue |
|---|---|---|
Content-Security-Policy | No | XSS attacks can inject and execute scripts |
X-Frame-Options | No | Clickjacking attacks possible |
X-Content-Type-Options | No | MIME sniffing attacks possible |
Strict-Transport-Security | No | Downgrade to HTTP possible |
Referrer-Policy | No | URL leakage in Referer headers |
Every absent header is a finding to note in your report.
Step 3: Cookie flag analysis
# Log in to DVWA, then inspect the Set-Cookie header:
$ curl -c cookies.txt -d "username=admin&password=password&Login=Login" \
http://localhost:8080/login.php -I
HTTP/1.1 302 Found
Set-Cookie: PHPSESSID=s3cr3tsessionid; path=/
Set-Cookie: security=low; expires=Thu, 01-Jan-2026 00:00:00 GMT; path=/Cookie flag analysis:
| Cookie | HttpOnly | Secure | SameSite | Issue |
|---|---|---|---|---|
PHPSESSID | Not set | Not set | Not set | Can be stolen via XSS; sent over HTTP; CSRF possible |
security | Not set | Not set | Not set | Readable by JS; not protected |
A session cookie without HttpOnly means any XSS payload can execute document.cookie and steal the session. A session cookie without Secure means it will be sent over unencrypted HTTP connections - vulnerable to interception.
Step 4: HTTP method enumeration
# Query which methods the server accepts:
$ curl -v -X OPTIONS http://localhost:8080/ 2>&1 | grep -i allow
< Allow: GET,HEAD,POST,OPTIONS,TRACE
# TRACE is dangerous - it echoes the request back, enabling XST (Cross-Site Tracing)
$ curl -v -X TRACE http://localhost:8080/ -H "Cookie: PHPSESSID=abc123" 2>&1
< HTTP/1.1 200 OK
<
TRACE / HTTP/1.1
Host: localhost:8080
Cookie: PHPSESSID=abc123 ← server echoed the cookie back in the response body!TRACE method should be disabled on production servers. With an XSS payload that fires a TRACE request, HttpOnly cookies can be exfiltrated (because the server echoes them in the response body, not in document.cookie).
# Try PUT - if enabled, can lead to file upload:
$ curl -v -X PUT http://localhost:8080/test.php -d "<?php phpinfo(); ?>"
# If 201 Created: arbitrary file write. If 405 Method Not Allowed: PUT is blocked.Step 5: Error page information disclosure
# Trigger a 404:
$ curl -v http://localhost:8080/doesnotexist
< HTTP/1.1 404 Not Found
< Server: Apache/2.2.8 (Ubuntu) DAV/2
# Apache version in error page confirms server header
# Trigger a PHP error with invalid input:
$ curl "http://localhost:8080/vulnerabilities/sqli/?id='"
# If verbose errors are on:
# Warning: mysql_fetch_array() expects parameter 1 to be resource,
# boolean given in /var/www/dvwa/vulnerabilities/sqli/source/low.php on line 15The PHP error reveals:
- The absolute server path:
/var/www/dvwa/ - The database type: MySQL
- The source file name and line number
- The fact that input reaches a
mysql_fetch_arraycall - confirming SQL injection potential
Solution
# 1. Server version banner
curl -I http://target/
# 2. Security headers audit
curl -v http://target/ 2>&1 | grep "^<" | grep -vE "^< (Date|Content)"
# 3. Cookie flags
curl -c /dev/null -v -L -d "user=admin&pass=password" http://target/login \
2>&1 | grep -i "set-cookie"
# 4. HTTP method enumeration
curl -X OPTIONS http://target/ -v 2>&1 | grep -i allow
# 5. Error page content
curl http://target/DOESNOTEXIST
curl "http://target/input?val='"Key takeaway: Before writing a single exploit, an attacker reads headers, cookies, and error messages. The server version in Server:, the language in X-Powered-By:, the session ID format in Set-Cookie:, and the missing security headers all contribute to the attack strategy. Passive reconnaissance against HTTP responses is zero-noise, zero-touch - you're reading what the server volunteers, not actively probing.