Back to Blog
On this page8 sections

// tutorial

Auth bugs QA can catch without being a pentester

qa.codesqa.codes · 13 June 2026 · 9 min read
IntermediateManual QASecurity
security-testingauthbugs

You do not have to be a pentester to catch the auth bugs that matter most. Here are the ones that surface during ordinary functional QA.

part ofSecurity testing for QA

There's a belief that security testing belongs to a separate team with specialist tools, and that QA should stay in its lane. For deep penetration testing, fine. But a large share of the auth bugs that cause real incidents aren't subtle exploits — they're functional defects in plain sight, findable with two browser tabs and a habit of asking "what if I'm not supposed to do this?" None of what follows requires exploit tooling, payloads, or anything you'd need permission to run. It's just functional testing pointed at the auth layer.

You need two accounts

Almost every check here works the same way: create two users with different permissions — say, User A and User B, or a regular user and an admin — and try to make one of them touch the other's stuff. That's the entire setup. Keep both logged in, in separate browser profiles, and you're ready.

1. The object you shouldn't be able to see

This is the big one. Log in as User A, open one of their records, and note the URL or the ID — /orders/1024. Now, as User B, request that same ID. Do you get A's order? That's broken object-level authorization (IDOR), and it's the single most common serious web vulnerability. It needs no tooling — just changing a number in a URL while logged in as the wrong person.

2. The action you shouldn't be able to take

Same idea, for actions instead of data. Find something only an admin can do — delete a user, change a price, export a report. Then try to trigger it as a regular user: directly hit the endpoint, or unhide the button in dev tools. If the server performs the action because the UI hid the button but the API never checked the role, that's a missing server-side authorization check. The UI hiding a control is not access control.

3. Does logging out actually log you out?

Log in, copy a working request (or just keep a tab open), then log out. Now replay the old session — reuse the tab, resend the request. Are you still in? A session that stays valid after logout means a stolen or shared session never dies. Same test for "log out everywhere" and "change password": both should invalidate existing sessions, and frequently neither does.

4. Session expiry and "remember me"

Leave a session idle past its supposed timeout and come back — are you still logged in long after you should've been kicked out? Then check the opposite: does a session expire mid-task and lose the user's work without warning? Both are bugs. "Remember me" deserves its own look: how long does it really last, and does unticking it actually shorten the session?

5. The password reset flow

Reset flows are deceptively risky. A few functional checks that catch real bugs: does the reset link still work after it's been used once (it shouldn't)? Does it still work a day later (it should expire)? If you request two resets, does the first link get invalidated? And does the reset response reveal whether an email is registered — "no account with that email" versus a generic "if that email exists, we've sent a link"? That difference is account enumeration, and the reset flow is worth a dedicated pass of its own.

6. Error messages that say too much

On the login form, compare the message for a wrong password against the message for an email that doesn't exist. If they differ, an attacker can enumerate which emails are registered. The fix is a single generic message for both — and it's a one-line bug to report.

How to report these safely

Two rules. First, stay on test data and test accounts you're authorised to use — never touch real customer records to "prove" an IDOR. Second, report the defect, not a weaponised exploit: "as User B I could read User A's order at /orders/1024; expected 403" is a clear, actionable bug report. The security testing checklist covers the full QA-safe pass, and frames where functional QA stops and a specialist review begins.

The two-account auth pass

  • Request another user's record by ID — do you get a 403, or their data?
  • Trigger an admin-only action as a regular user (endpoint or unhidden button)
  • Replay a session after logout / password change — is it dead?
  • Confirm idle timeout and "remember me" behave as claimed
  • Reset links are single-use, expire, and don't reveal whether an email exists
  • Login errors don't distinguish "wrong password" from "no such account"
  • All findings reported as defects, on test data, with expected vs actual

// RELATED QA.CODES RESOURCES


// related

Tutorials·13 June 2026 · 8 min read

The password reset bugs I always test for

Password reset is a deceptively risky flow — token reuse, expiry, enumeration, and session handling all hide here.

security-testingauthbugs
Tutorials·13 June 2026 · 8 min read

How to test session expiry properly

A session that lives too long is a hole, one that survives logout defeats the point. Here is the session-expiry pass — idle, absolute, logout, reset, remember-me, and fixation.

security-testingauthsessionsbugs