Intercepting Proxies
An intercepting proxy is a tool that sits between your browser and the web server and shows you every HTTP request and response as it passes: the method, the URL, the headers, the cookies and the body, not just the finished page. ZAP (Zed Attack Proxy), the free open-source proxy long known as OWASP ZAP, is the example in this lesson; other intercepting proxies work the same way under different menu names.
Because the traffic flows through it, the proxy can keep a searchable history of every message, pause (intercept) a request so you can change it before it reaches the server, and replay a past request with different values. A tester uses this to see what the server does when the client sends something the real app never would, such as another user's order id, a higher role or no session at all.
Why it matters
Many serious web defects live in what the server trusts. If the server assumes the browser will only send order ids that belong to the logged-in user, changing that id in the proxy can reveal broken access control, A01 in the OWASP Top 10:2025 from the previous lesson, in minutes. A disabled button, a hidden field and client-side validation are only suggestions to the browser; the proxy lets you test the server, which is where security has to hold.
For the tester, the proxy turns a vague worry into repeatable evidence: the exact request, the one value you changed and the response. That is a bug report a developer can act on, and the history shows precisely what you sent, so you can show that an authorised test stayed inside its limits.
Where the proxy sits, and how to set it up safely
The proxy listens on a local address, for example 127.0.0.1:8080. You point a browser at it, and every request now travels browser to proxy to server, with each response coming back the same way. Unlike the DevTools Network panel, which records what one tab did, the proxy stands in the path and can hold a message before the server sees it.
Two set-up steps keep this safe. First, use a dedicated test browser profile, or a separate browser, that sends its traffic to the proxy, so your everyday logins and cookies never pass through it. Second, to read HTTPS the proxy ends the browser's encrypted connection itself and presents a certificate for each site, signed by its own certificate authority (CA). Trust that proxy CA in the test profile only, never system-wide or on a personal device, because a browser that trusts it accepts any certificate signed with its key, for any site. Remove it when the engagement ends.
- 1Test browserall traffic → proxyA dedicated profile that trusts the proxy CA certificate
- 2Scope checkIs this host on the authorised list?Proxy
Branch: Out of scope → passed on untouched: not intercepted, replayed or scannedCaution
Gate: in scope only
- 3HistoryA searchable record of each request and response; passive scanning reads itProxy
- 4Intercept and modifyPause it and change one id, role or session value
GET /api/orders/1043Optional - 5Authorised targetResponds; the response returns through the proxy into history
Throughout steps 3–5 Inside the authorised scope · written permission names these hosts
Back to step 3 Replay: resend from history with one value changed
History, intercept-and-modify, and replay
The history (the History tab in ZAP; some tools call it HTTP history) lists every request and response, with filters such as method, status code and a URL pattern that matches one host, so you can find the one call you need among hundreds. Intercept-and-modify pauses a request at the proxy: you edit a header, a parameter or the body, then let it continue, so the server receives your version, not the browser's.
Replay sends a request from the history again with one value changed, so you can compare responses; in ZAP you right-click it and choose "Open/Resend with Request Editor". Replay turns "the button is greyed out" into a fact about the server. Three replays cover most first checks:
- Changed id: keep your own session and ask for another user's order or profile. The server should refuse.
- Changed role: resend, with a normal user's session, a request that only an admin should make, or set a
rolefield fromusertoadminwhen updating your own test account. The server should refuse or ignore it. - Changed session value: remove the session cookie, or reuse one you have logged out of. The server should answer
401 Unauthorizedor send you to log in, never return the data.
Try it: HTTP Headers Parser Try it: API Authentication Tester
Passive scanning: a lead, not a verdict
While traffic flows through it, the proxy can inspect each message and raise alerts without sending anything of its own. This is passive scanning, and because it only reads traffic you were already exchanging, it is safe to leave on during ordinary testing.
An alert is a lead, not a verdict: it can be a false positive, and passive scanning misses anything that needs a request the app never made. Confirm each alert by hand before reporting it. Active scanning, where the tool sends its own crafted attack requests, is a separate, higher-risk mode that needs explicit authorisation and is beyond this lesson.
- Missing header: a response without
Strict-Transport-SecurityorContent-Security-Policy. - Weak cookie: a session cookie set without the
SecureorHttpOnlyattribute (RFC 6265). - Leak: a token in a URL query string, or an error page that shows a stack trace.
Worked example: an access-control check by replay
You are authorised, in writing, to test your team's staging shop, and staging.shop.example is in the proxy scope. Logged in as your own test user, you open one of your orders and find its request in the history. In the request editor you change only the order id to one owned by a second test user, keep your own session cookie, and resend.
The secure result is 403 Forbidden or 404 Not Found: the server checks that the order belongs to the caller. A 200 OK with the other user's order is broken access control, an insecure direct object reference (IDOR), and you already hold the exact request and response for the bug report.
GET /api/orders/1042 HTTP/1.1
Host: staging.shop.example
Cookie: session=<your own test session>
# Replay with one change: an order id that is not yours
GET /api/orders/1043 HTTP/1.1
Host: staging.shop.example
Cookie: session=<your own test session>
# Secure response: 403 Forbidden or 404 Not Found
# Broken access control: 200 OK with another user's orderCommon mistakes
- Testing through your everyday browser profile, so personal logins and cookies end up in the capture and in screenshots.
- Trusting the proxy CA system-wide or on a personal device, then forgetting to remove it.
- Taking a greyed-out button or client-side validation as proof of a control instead of replaying the request to the server.
- Leaving the scope open, so replay or scanning can reach hosts you have no permission to test.
- Reporting a passive-scan alert as a confirmed defect without checking it by hand.
- Changing two values at once, or not saving the exact request and response, so nobody can tell what caused the result.
The QA perspective
On a team, the intercepting proxy is a functional tester's tool as much as a specialist's. You use it in ordinary feature testing to see the requests behind a flow, reproduce a bug exactly, and run the few access-control checks every authenticated feature deserves: can I reach another user's record, can I act above my role, does the server check the session on every request. Deeper and active testing belongs with security specialists and the OWASP Web Security Testing Guide.
Agree scope and authorisation with the environment owner first, prefer staging to production, and use only the test accounts you were given. In the bug report, include the request and response with secrets masked, the one value you changed and the expected secure behaviour, so a developer can confirm the fix with the same replay.
Practice exercise
Plan a role check and a session check by replay
You are authorised, in writing, to test your team's staging shop, and its host is in the proxy scope. The material shows a request captured while your admin test user opened the user list, and the session cookie of your customer test user.
Plan two replays: one that tests the role check and one that tests the session check. For each, say what you change, what you keep and the expected secure response, then say what you confirm before sending.
# Captured as your admin test user
GET /api/admin/users HTTP/1.1
Host: staging.shop.example
Cookie: session=a91e... (admin test user)
Accept: application/json
# Session cookie of your customer test user
Cookie: session=7c03...- Find the value that tells the server who is calling.
- Plan the role replay: what you swap and what stays as captured.
- Plan the session replay: what you remove and what stays as captured.
- List what you confirm before sending anything.
Show the model answer
Both replays change only the session cookie: it is the only value here that tells the server who is calling, and the server works out the user and role from that session. The method, path and other headers stay exactly as captured, so any change in the response comes from that one value.
Role replay: replace a91e... with the customer session 7c03... and resend. Secure: 403 Forbidden, or 404 Not Found if the app hides admin routes. A 200 OK with the user list means a customer can act as an admin, which is broken access control.
Session replay: remove the Cookie header and resend. Secure: 401 Unauthorized or a redirect to the login page. A 200 OK with data means the endpoint does not check authentication at all.
Before sending, confirm that the host is in the proxy scope, that your written authorisation covers this host, this date and this kind of check, and that both accounts are test accounts you were given. Starting with GET helps: RFC 9110 defines it as a safe method, so a replay should not change data. If anything is unclear, stop and ask.
Frequently asked questions
Is an intercepting proxy the same as browser DevTools?
They overlap. The DevTools Network panel shows a tab's requests and lets you copy or resend some of them, which is enough for many checks. A proxy adds a true intercept step that holds the request before it reaches the server, one history across tabs and clients, and passive scanning, and it can capture non-browser clients such as a mobile app or curl. Start with DevTools; use a proxy when you need to change a request in flight or capture more than one client.
Why do I have to install a certificate?
HTTPS encrypts traffic between browser and server, so to read and change it the proxy ends the browser's connection itself and presents a certificate signed by its own CA. Your test browser accepts that only if it trusts the proxy CA. Install it in a dedicated test profile, never system-wide or on a personal device, and remove it when you are done.
Can I use a proxy on any website I want to test?
No. Use it only on systems you own or have explicit written permission to test. The proxy sends real, modified requests to a real server, and doing that without authorisation is not testing and is illegal in many countries. Set the proxy scope to the authorised hosts and leave everything else out.
What is the difference between passive and active scanning?
Passive scanning only reads the traffic you were already sending and receiving, so it is safe to leave on. Active scanning sends crafted requests of its own to probe for weaknesses; it is higher risk, can change data, and needs explicit authorisation. This lesson stays with passive scanning and manual, one-request-at-a-time checks.
References
- OWASP Web Security Testing Guide (WSTG)The reference methodology for testing web applications and APIs for security weaknesses, test by test.
- NIST SP 800-115: Technical Guide to Information Security Testing and AssessmentHow to plan and run security assessments: review, target identification, vulnerability validation and reporting.
- OWASP Top 10:2025The ten most critical web application security risks, with how to test for and prevent each.
- RFC 9110: HTTP SemanticsThe meaning of HTTP methods, header fields, status codes and content negotiation, independent of the wire version.
Practise with Mutqan tools
Compose and send HTTP requests (method, URL, headers, auth, body) and inspect the response — a lightweight Postman in your browser.
Test Bearer, Basic, API-key and custom-header authentication against an endpoint and compare authorised vs unauthorised responses.
Parse raw HTTP request/response headers into a structured table with explanations.
Parse Set-Cookie headers and check Secure, HttpOnly, SameSite, Domain, Path, expiry and size best practices.
Grade HTTP security headers (CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, COOP/CORP) from pasted headers or a public URL.
See exactly what your client sends: method, headers, query, body, IP and TLS info.
Go deeper
Your progress on this topic
Not started
Mark the topic complete when you have studied it and done the exercise.
Sign in to track your progress
Mark topics complete, continue where you left off and unlock specialisation exams.