Skip to content
CWE-89A03:2021 – Injection

Testing Methodology

A repeatable order of operations for finding and confirming SQL injection: map the surface, probe every parameter, fingerprint, extract the minimum to prove impact.

A Repeatable Order

Ad-hoc testing misses injection points and wastes time on dead ends. A consistent methodology finds more and documents itself as it goes.

The phases:

  1. Map every parameter that could reach a query.
  2. Probe each one for the injection signal.
  3. Confirm the signal is really SQL execution.
  4. Fingerprint the engine.
  5. Determine context and technique.
  6. Extract the minimum needed to demonstrate impact.
  7. Document as you go.

Always within an authorized scope. Everything here assumes written permission for the target.

1. Map the Attack Surface

Enumerate every input that could reach the database — the point is to test parameters others skip.

  • URL query parameters and path segments.
  • POST bodies — form-encoded, JSON, XML, multipart.
  • HTTP headers. User-Agent, Referer, X-Forwarded-For, and Cookie values frequently land in logging or analytics queries. These are classic second-order sources and are routinely unvalidated.
  • Cookies, including session-adjacent values used for personalisation.
  • API parameters — filter, sort, field-selection, pagination. See APIs and GraphQL.
  • File uploads — names and parsed content that reach a query.
  • Out-of-band inputs — anything imported from another system.

Use the OpenAPI/Swagger spec, GraphQL introspection, and the front-end JavaScript bundle to enumerate parameters faster than crawling. Note which parameters are numeric, which are strings, and which look like identifiers (sort, order, column) — that shapes the probes.

2. Probe Each Parameter

Test one parameter at a time so you know which one responded. For each, send the standard signal set and record the response:

'                 -> error or changed response?
''                -> back to normal? (string context confirmed)
\                 -> error? (escaping / MSSQL)
' AND '1'='1      vs   ' AND '1'='2      (differential)
 AND 1=1          vs    AND 1=2          (numeric differential)
4-1               -> returns record 3?  (arithmetic, numeric context)
' AND SLEEP(5)-- -                        (timing, last resort)

The differential pair is the strongest signal, because both members are syntactically valid — a difference between them can only be semantic. See Detection for the full rationale and per-engine timing probes.

3. Confirm It Is Real

Rule out false positives before investing further — see Detection. Briefly:

  • Re-run differentials several times; caching and A/B tests produce spurious differences.
  • Vary the sleep duration and confirm the response time tracks it.
  • Test with inert-but-unusual characters to see whether the app just errors on anything odd.
  • Confirm a WAF is not producing the differential instead of the database.

A finding you cannot reproduce on demand is not yet a finding.

4. Fingerprint the Engine

Everything past this point is engine-specific, so identify it before choosing payloads. Error text usually names the product; if errors are hidden, the concatenation and comment probes distinguish the families in a request each. Full method in Detection, and the per-engine specifics in the DBMS Reference.

5. Determine Context and Technique

Establish the injection context — the prefix to break out and the suffix to stay valid — then pick a technique by what the application shows you:

The Payload Generator produces the right payload for a given engine/technique/context, and the Sandbox lets you rehearse the technique against a real database first.

6. Extract Enough to Prove Impact — and No More

The goal of an authorized test is to demonstrate impact, not to exfiltrate the database. Extract the minimum that makes the risk undeniable, then stop.

Proportionate proof:

  • The database version and current user — proves execution.
  • The list of table names — proves schema access.
  • The count of rows in a sensitive table, and one or two redacted sample values — proves data access without hoarding real records.

Avoid:

  • Dumping entire tables of personal data. You become a custodian of records you did not need, and you increase the harm if your own notes leak.
  • Extracting production credentials you will not use, beyond noting that they are reachable.
  • Any write, file, or command operation without separate explicit authorization — see RCE and File Read and Write.

If the client needs a full-dump demonstration for a specific reason, agree it in advance and handle the data per the engagement's rules.

7. Document as You Go

Record while testing, not afterwards from memory. For each finding capture:

  • The exact request — URL, method, parameter, and the literal payload.
  • The response evidence — the differential, the timing, the error, or the extracted value (redacted).
  • The context and engine, so the remediation advice is specific.
  • The privilege level reached, and whether it escalates to file access or RCE.
  • Any state you changed and every artefact you left, for cleanup.

A finding a developer can reproduce from your notes in one request is worth far more than one they have to rediscover. Pair each finding with the matching prevention guide so the report tells them how to fix it, not just that it is broken.

Coverage Checklist

  • Every URL, body, header, and cookie parameter probed individually.
  • JSON and multipart bodies tested, not only form-encoded.
  • Numeric parameters tested without quotes; identifier parameters (sort, order) tested for the identifier context.
  • Headers and stored fields tested for second-order injection.
  • APIs and GraphQL resolvers included — see APIs and GraphQL.
  • Each candidate confirmed against false positives before reporting.
  • Impact demonstrated proportionately; no gratuitous data extraction.
  • Every payload, artefact, and state change recorded for the report and cleanup.