eJPT study materials
eJPT study resources

WAF, SOAR and a Six-Second Delay

eJPT · Put your knowledge to work in context.

All case studies

WAF, SOAR and a Six-Second Delay

You are testing shop.example.com. The login form locks an account after 5 failed attempts for 15 minutes. Cloudflare returns 403 after roughly 30 requests per minute from a single IP, and your browser fingerprint is also getting flagged after heavy fuzzing. On /product?cat=3 you suspect time-based blind SQL injection: appending ' AND SLEEP(5)-- - returns after about 6 seconds - but roughly one request in four comes back 403. In the same session you find GET /api/v1/invoices/1043 returns a PDF, and changing the number to 1044 returns 200 with a different company's invoice. The client's SOC watches for 'attacks' and will phone you if they see noise. You have four days remaining.

1. How do you confirm the SQL injection without tripping the WAF repeatedly or looking like an attack?

Read the worked answer

Prove it with as few requests as possible, and prove it in a way that distinguishes injection from network jitter.

  1. Baseline first. Measure 10 clean requests to cat=3; record median and spread. A single 6-second response is not evidence - it is a slow CDN node.
  2. Try boolean before time-based. AND 1=1 vs AND 1=2 producing different page content is a non-delay confirmation and costs two requests. Time-based is the fallback.
  3. If time-based is all you have, make the sleep conditional so only the true branch delays: AND IF(1=1,SLEEP(5),0). Three repeats, spaced a minute apart, all at baseline-plus-5s, is a defensible result.
  4. Throttle deliberately. Stay under ~20 requests/minute to keep clear of the 403 threshold, single-threaded. If you use sqlmap: --threads=1 --delay=4 --technique=T --random-agent --tamper=space2comment, and scope it with --dbms so it stops guessing.
  5. Prove access, not data. Extract version(), current_user(), and a single count from a non-sensitive table. Then stop. You are not exfiltrating a customer database on a Tuesday.
  6. Deconflict with the SOC first. Send them your source IP, user agent, and the time window. Thirty seconds of email prevents a two-hour incident call and a scope dispute.

2. You have a confirmed cross-tenant IDOR. How far do you take it?

Read the worked answer

Far enough to make the severity undisputable, no further.

  • Verify with controlled identities. Two accounts you created in different tenants, sequential requests, screenshots showing tenant A's session receiving tenant B's invoice PDF. Without that, the client's developer will argue it is a caching artefact.
  • Bound the demonstration. Enumerate a handful of IDs - enough to show it is sequential and unauthenticated by ownership, not enough to be a data breach you caused. Five or six is plenty; a loop to 100,000 is now exfiltration and changes your legal position.
  • Redact. Mask names, amounts and addresses in the evidence; store the raw PDFs encrypted and hand them over only under the engagement's data-handling clause.
  • Test the negative case: does a completely different tenant's ID return 403, or does a deleted/foreign ID also return data? That tells you whether the check is missing or merely broken for a subset.
  • Severity: high. Cross-tenant data exposure, trivially reachable, no authentication bypass needed. Fix is object-level authorisation on every invoice route - small code change, high impact reduction.

3. How do you sequence the remaining four days and the reporting?

Read the worked answer

Report the IDOR inside 24 hours; spend the calendar on the SQL injection.

The reasoning is about fix cost versus exposure, not about which bug is 'cooler':

  • The IDOR is already confirmed, exposes real customer data right now, and is likely a one-line authorisation check. It cannot wait for the final report. Send an interim advisory to the client today, with reproduction steps and a suggested fix, and note that if the exposed invoices contain real customer records, their breach-notification obligations may already be triggered - that is the client's legal call, not yours, but they need it today.
  • The SQL injection is not yet confirmed and confirming it is slow by design because of the WAF. Give it two days: one to confirm and scope, one to establish impact (version(), privilege level, whether stacked queries or file read are available). If it is still ambiguous after two days, report it as 'time-based injection confirmed, privilege escalation not established' - that is a complete finding.
  • Day three: finish the authenticated areas with the test accounts, including the account-lockout policy (testing it deliberately locks real users - use only client-supplied test accounts).
  • Day four: report and read-out. The read-out should lead with the two-day-old IDOR that is already been fixed, not with a four-day SQLi saga.