Python › Python for Pentesters

Sessions, cookies, and authentication

5 min read Intermediate 5 sections

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 styleHow to send it
Cookie / sessionSession() auto-stores after login; or s.cookies.set(...)
Bearer / JWTs.headers["Authorization"] = "Bearer <token>"
Basic authrequests.get(url, auth=("user", "pass"))
API key headers.headers["X-API-Key"] = "<key>"
API key paramparams={"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?

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.proxies for inspection.

Quick quiz

That completes Python for Pentesters. From here the course moves into recon automation, building real tools from these pieces.

Was this lesson helpful?