Authenticated Scanning and Access-Control Testing for a Retail API
Vantage Retail's storefront exposes about 1,200 REST endpoints behind an API gateway. Authentication uses OpenID Connect with 15-minute access tokens; admin accounts require MFA, customer accounts do not. Scope checks are enforced at the gateway from token claims, and each microservice also reads the token. The nightly DAST scan runs unauthenticated, finishes in about nine hours and reports three findings, all on the login page. A business analyst suspects that order retrieval is vulnerable to insecure direct object references because the order ID appears as a sequential number in the URL. Staging mirrors production configuration except that the test identity provider issues tokens to dedicated test users, and its data is synthetic. The security lead wants authenticated scanning and a manual access-control test set before the next release, but the only test environment is shared with performance testing between 22:00 and 06:00.
1. How do you configure authenticated scanning so the results are trustworthy? Address MFA, short-lived tokens, account lockout and the nine-hour runtime.
Read the worked answer
Accounts and MFA: create dedicated test users per role in the staging identity provider. Handle MFA deterministically - a seeded TOTP secret for the test account, or a test-only IdP rule that is flagged, monitored and impossible to enable in production. Never use a real employee's second factor.
Session handling: record the login as a session macro so the scanner can re-authenticate. With 15-minute tokens either extend token lifetime for these accounts or let the scanner re-run the macro on a 401. Many scanners also accept a manually injected cookie or bearer token, which is more reliable than replaying the login form.
Lockout: disable or raise the lockout threshold for the dedicated accounts, otherwise the scanner locks itself out mid-run and the rest of the scan silently becomes unauthenticated. Verify authentication worked by including a canary URL that only returns 200 when logged in, and check that responses are not redirects to the login page.
Roles: run separate scans per role, because gateway scope checks differ and a mixed crawl hides privilege problems.
Runtime: 1,200 endpoints in nine hours unauthenticated will be longer authenticated. Shard by path group across parallel workers, schedule within the 22:00–06:00 window, prioritise changed endpoints, and run the full sweep weekly with a targeted sweep per release. Keep scans non-destructive against synthetic data, and record the configuration as test evidence.
2. Design the manual test set for broken access control on the order API and explain why the scanner cannot be relied on for it.
Read the worked answer
Test set (two accounts per role, all traffic through an intercepting proxy so every request can be edited and captured):
- Horizontal: request user A's order using user B's token; expected 403 or 404 with no data in the body.
- Object enumeration: try sequential and predictable IDs, plus identifiers harvested from another tenant, against every endpoint that returns an object.
- Vertical: call admin endpoints with a customer token, and note any endpoint that behaves differently by role rather than rejecting outright.
- Method and content tampering: change GET to PUT or DELETE, add fields such as role, tenantId or userId to request bodies (mass assignment), and try duplicate parameters.
- Token manipulation: alter claims and confirm signature validation rejects them; test algorithm and key-ID handling only within the agreed scope.
- Forced browsing: reach endpoints that are not linked in the UI but appear in JavaScript bundles or the OpenAPI document.
Why the scanner cannot cover it: authorisation is about object ownership and business rules. A DAST tool has no concept of 'this order belongs to someone else'; unless it correlates two identities and understands the expected relationship, a 200 response looks like success. Most scanners do not do this reliably, so a clean scan is a false negative, not evidence of security. Each manual test needs a stated expected result so a failure is unambiguous and can be retested.
3. How do you judge coverage and decide when access-control testing is done?
Read the worked answer
Measure coverage as combinations of endpoint x role x object-ownership scenario, not as requests sent or hours spent.
Build the inventory from the gateway routes and OpenAPI specification, then mark which combinations are in scope by risk: order data, payment methods and addresses first, catalogue browsing last.
Done means every state-changing and data-returning endpoint has at least one negative test per role; multi-tenant boundaries are tested with objects drawn from a second tenant, not just a second user; results are reviewed by someone other than the author; and any response returning another user's data is proven with captured request and response evidence.
Watch for false comfort:
- Test accounts with unrealistic privileges (a test admin with a wildcard scope) can mask vertical escalation problems, so model roles as production does.
- If staging lacks a gateway policy that production enforces, results do not transfer; note the difference and test the missing layer some other way.
- The 22:00–06:00 window limits how much manual work is possible; if time runs out, report the residual untested combinations explicitly rather than claiming full coverage.
Finally, feed the tested combinations back to the requirements: endpoints that returned data without an ownership check should gain a story-level acceptance criterion so the regression suite can cover them next time.