Python › Python for Pentesters
Sessions, cookies, and authentication
Most of what’s worth testing lives behind a login. The Session object is how you get there: it logs in once and stays logged in across every following request, just like a browser does — but under full programmatic control. This one object is the backbone of the highest-value web tests there are.
You'll learn to
- Use a Session to stay authenticated across requests
- Send every common auth scheme from code
- Run an authorization (IDOR / auth-matrix) test
The Session object
import requests
s = requests.Session() # a Session persists cookies + settings
s.headers.update({"User-Agent": "recon/1.0"}) # applied to EVERY request on s
# Log in once — the session stores the auth cookie automatically:
s.post("https://example.com/login", data={"user": "admin", "pass": "x"})
# Later requests are authenticated because the cookie rides along:
r = s.get("https://example.com/dashboard")
# Manual cookie / token auth:
s.cookies.set("session", "abc123")
s.headers["Authorization"] = "Bearer eyJ..." # bearer-token auth
A Session remembers cookies between requests, so you log in once and stay logged in. It also lets you set headers applied to every request. This mirrors how a browser maintains a logged-in state — but you control every detail.
Every auth scheme is just headers, cookies, or params
| Auth style | How to send it |
|---|---|
| Cookie / session | Session() auto-stores after login; or s.cookies.set(...) |
| Bearer / JWT | s.headers["Authorization"] = "Bearer <token>" |
| Basic auth | requests.get(url, auth=("user", "pass")) |
| API key header | s.headers["X-API-Key"] = "<key>" |
| API key param | params={"api_key": "<key>"} |
Every scheme reduces to a header, a cookie, or a parameter — all things you already know how to build.
The highest-value test: IDOR and the auth matrix
# IDOR sweep: as a low-priv user, can you reach objects you shouldn't?
for oid in range(1, 100):
r = s.get(f"https://example.com/api/orders/{oid}")
if r.status_code == 200 and len(r.text) > 50:
print(f"[idor?] order {oid} accessible")
Even more powerful is the auth matrix — hold two sessions (say admin and a normal user) and replay each privileged action with both, watching for actions the normal user shouldn’t be able to do but can.
admin = requests.Session() # logged in as admin
user = requests.Session() # logged in as a normal user
for action_url in privileged_actions:
a = admin.get(action_url).status_code
u = user.get(action_url).status_code
if u == 200: # the normal user got in too — broken access control
print(f"[finding] user can access {action_url}")
Checkpoint
You want to confirm whether a normal user can perform an admin-only action. What two-session technique do you use, and what result would be a finding?
The auth matrix: hold one admin session and one normal-user session, then send the same admin-only action through both. If the normal user's request returns 200 (succeeds), that's a broken-access-control finding — the server isn't enforcing the privilege check.
Try it yourself
Create two requests.Session() objects representing two privilege levels (you can simulate by setting different cookies). Loop over a small list of “action” URLs and print each URL with both sessions’ status codes side by side. That grid is an auth matrix in miniature.
Summary
A Session persists cookies and headers across requests, so you log in once and stay authenticated — the foundation of testing anything behind a login. Every auth scheme is a header, cookie, or param you can set. Sessions enable the highest-value web tests: IDOR sweeps (reach objects you shouldn’t) and the auth matrix (replay privileged actions across privilege levels to find missing server-side checks). Always make authenticated requests through the same session that holds the login.
Key takeaways
requests.Session()keeps you logged in across requests.- Bearer, Basic, cookie, and API-key auth are all just headers/cookies/params.
- The auth matrix (two sessions, replay each action) finds broken access control.
- Route a session through Burp with
s.proxiesfor inspection.
Quick quiz
That completes Python for Pentesters. From here the course moves into recon automation, building real tools from these pieces.