scanrub
SQL Injection

SQL Injection

3 min read 163 reports analyzed ScanRub Research
Share
Live Playground · Powered by this research
SQL Injection Pattern Detector

Paste a URL parameter value or a query string - we'll flag payloads that resemble SQL injection.

Quote charactersDETECTED
Comment syntaxNot present
UNION/SELECTNot present
Boolean logicDETECTED
Time delay functionsNot present
Stacked queriesNot present
Match to HackerOne payload' OR '1'='1
Exact match to a payload from our HackerOne corpus. This has been used in real disclosed reports.
Payloads from this research (10 total)
' OR '1'='1
1' UNION SELECT NULL,NULL,NULL--
1' AND SLEEP(5)--
'; WAITFOR DELAY '0:0:13'--
These payloads were synthesized from real HackerOne disclosures. Click any payload to copy it, then paste it into the tester above to see how our detection classifies it.

Summary

Classic SQLi reports clustered around:

  • URL/POST parameter injection into legacy ASP/PHP pages - ?id=1' OR '1'='1
  • time-based blind via WAITFOR DELAY (MSSQL), SLEEP() (MySQL), pg_sleep() (PostgreSQL)
  • Header-based SQLi via Referer, User-Agent, X-Forwarded-For when those values are logged into the database
  • JSON-body SQLi via API parameters
  • GraphQL filter clauses
  • JWT kid SQLi
  • UUID lookup endpoints accepting non-UUID values
  • Search endpoints concatenating LIKE patterns
  • ORM bypass via raw queries / unsafe builders. Sqlmap covers most surface but reports show several patterns where Sqlmap's default profile misses: header/cookie injection, complex JSON injection, GraphQL.
◈ flow diagram
User InputApplication …SQL Query Co…Database Eng…Query ResultApplication …
◈ chart
Critical
57
High
65
Medium
33
Low
8

Top Affected Components / Targets

  • Legacy ASP/PHP/JSP pages with id, page, search, filter parameters
  • Search endpoints with LIKE patterns
  • Header-logged endpoints (analytics, error pages)
  • REST APIs accepting JSON bodies
  • GraphQL query filter / order-by
  • JWT validators looking up keys by kid
  • Login forms that look up users by username via SQL

Common Attack Vectors

  • URL/POST parameter ' OR '1'='1, ' UNION SELECT ...
  • Time-based MSSQL: '; WAITFOR DELAY '0:0:13'--
  • Time-based MySQL: ' AND SLEEP(13)--
  • Time-based PostgreSQL: '; SELECT pg_sleep(13)--
  • Boolean-based: ' AND '1'='1 vs ' AND '1'='2
  • Error-based: ' AND extractvalue(rand(),concat(0x7e,version()))--
  • Header injection: Referer/User-Agent/X-Forwarded-For containing payload
  • JSON body: {"name":"x' AND SLEEP(5)--"}
  • GraphQL filter: where: { name: { _eq: "x' OR 1=1 --" } }
  • JWT kid: {"kid":"test' UNION SELECT 'attacker_secret'--"}

Common Payloads

  • ' OR '1'='1
  • 1' UNION SELECT NULL,NULL,NULL--
  • 1' AND SLEEP(5)--
  • '; WAITFOR DELAY '0:0:13'--
  • '; SELECT pg_sleep(13)--
  • 1)) OR 1=1--
  • ' AND extractvalue(rand(),concat(0x7e,version()))--
  • ' AND (SELECT*FROM(SELECT(SLEEP(5)))a)--
  • 1' OR if(1=1,sleep(5),0) --
  • ' AND 'x'='x + ' AND 'x'='y (boolean differential)

Detection Strategy

Stage 1: canonical Sqlmap

Keep current Sqlmap-based module.

Stage 2: header injection

Inject time-based payloads into Referer / User-Agent / X-Forwarded-For / Cookie and detect latency differential.

Stage 3: JSON SQLi

For endpoints accepting JSON bodies, run Sqlmap with --data and --headers including Content-Type: application/json.

Stage 4: GraphQL filter

On detected GraphQL endpoints, identify filter / where / order-by paths in the schema (introspection helps) and submit time-based payloads.

Stage 5: boolean-based fuzz

For parameters where time-based fails (timeouts blocked), apply a boolean differential (' AND '1'='1 vs ' AND '1'='2) and detect content-length differences.

Stage 6: UUID/integer-only validators

When a parameter expects UUID or int, submit non-UUID value with a quote and observe error messages - type-mismatch errors that include SQL fragments betray injection.

Confidence: time-based + 3-of-3 confirmation = high; boolean differential + 3 datapoints = high; error-message reveals SQL = high.

Tip: Testing tools that run these checks in parallel across every discovered endpoint can cut the time required substantially compared to fully manual testing, as long as they confirm findings with more than one signal to keep the false-positive rate down.

False-Positive Notes

  • Time-based probes need stable network baseline - repeat 3 times.
  • Sqlmap is high-quality but misses headers, cookies, JSON, and GraphQL by default - that's where the additive value lies.
  • Error messages alone are a finding only when SQL fragments appear; generic 500 pages don't qualify.

How to Test

Manual Testing Methodology

Here is a systematic approach to identifying SQL Injection vulnerabilities in a target application.

Step 1: Reconnaissance and Surface Mapping

Before testing, map all input vectors that could be affected. Identify parameters, headers, cookies, and request bodies that interact with the vulnerable component. A proxy such as Burp Suite or OWASP ZAP, paired with normal browsing of the target, is usually enough to build this list.

Step 2: Baseline Request

Send a legitimate request and record the normal response: status code, content length, response time, and any identifying tokens. This baseline matters because it's what you'll compare later responses against once payloads are involved.

Step 3: Payload Injection

Inject test payloads into each identified input vector one at a time. Start with benign detection payloads before escalating to anything that could actually trigger the vulnerability. For SQL Injection specifically, Test boolean-based (OR 1=1 vs OR 1=2), time-based (SLEEP(5) / WAITFOR DELAY), and UNION-based payloads against every parameter, one at a time, and in a database-neutral form before switching to DBMS-specific syntax once the backend is fingerprinted.

Step 4: Response Analysis

Compare the response against your baseline, looking specifically for a differential response between the true and false boolean payloads, a reproducible delay proportional to the injected sleep value on a second independent trial, or a UNION result set that reflects extra columns back into the page — a single slow response is not enough on its own, since network jitter produces the same signal.

Step 5: Confirmation

Once a potential vulnerability is detected, confirm it with at least a few independent test cases to rule out coincidence. Document the exact request and response as proof. For SQL Injection, a confirmed finding typically means showing that attacker-controlled input changes the application's behavior in a way that matters for security, not just that a payload was reflected somewhere harmless.

Real-World Impact

Real-World Impact

SQL injection remains one of the most damaging vulnerability classes in production systems. When exploited, attackers gain direct access to the underlying database, which opens the door to mass data exfiltration (customer records, credentials, financial data), privilege escalation to database administrator, and in some configurations, operating system command execution through xp_cmdshell on MSSQL or LOAD_FILE and INTO OUTFILE on MySQL.

In disclosed bug bounty reports, SQL injection findings consistently receive critical severity ratings, and the window of exploitation before a bug is even discovered often stretches to weeks or months, even though patches tend to follow quickly once a report lands.

Organizations affected by SQL injection also face regulatory consequences under frameworks like GDPR, CCPA, and PCI DSS, on top of the direct costs of incident response and customer notification.

Prevention & Remediation

Prevention and Secure Coding

Preventing SQL Injection takes a defense-in-depth approach — no single control below is sufficient alone, but together they close off both the primary path and the most common bypasses.

Parameterized queries. Use parameterized queries or prepared statements as the primary control for every database call — never build SQL by concatenating or interpolating user input into a query string.

ORM query builders. Where an ORM is already in use, keep all query construction inside its builder API; a single raw-SQL escape hatch inside otherwise-safe code is a common source of the bug slipping back in.

Least-privilege database accounts. Run the application under a database account limited to exactly the tables and operations it needs — a successful injection against a read-only, single-schema account does far less damage than one against a shared admin login.

Stored procedures, reviewed. Stored procedures are not inherently safe; audit them for dynamic SQL built from parameters before treating them as a mitigation.

Defense in depth, not the primary control. Input validation and a WAF rule can catch obvious payloads, but treat them as a second layer — they are not a substitute for parameterization.

Source reports

A sample of the disclosed HackerOne reports this playbook was synthesized from.

Frequently Asked Questions

What is SQL Injection?
Classic SQLi reports clustered around: (1) URL/POST parameter injection into legacy ASP/PHP pages - `?id=1' OR '1'='1`; (2) time-based blind via `WAITFOR DELAY` (MSSQL), `SLEEP()` (MySQL), `pg_sleep()` (PostgreSQL); (3) Header-based SQLi via Referer, User-Agent, X-Forwarded-For when those values are logged into the database; (4) JSON-body SQLi via API parameters; (5) GraphQL filter clauses; (6) JWT kid SQLi; (7) UUID lookup endpoints accepting non-UUID values; (8) Search endpoints concatenating LIKE patterns; (9) ORM bypass via raw queries / unsafe builders.
How common is SQL Injection in bug bounty reports?
Scanrub's research corpus for this playbook is built from 163 disclosed HackerOne reports in this category, synthesized for detection and prevention guidance rather than reproduced verbatim.
How do I test for SQL Injection?
Map every input vector, record a baseline response, then inject targeted test payloads one field at a time and compare the response for timing, length, error, or reflection differences from that baseline. The "How to Test" section above walks through the full methodology for this specific vulnerability class.
What is the single most effective fix for SQL Injection?
Use parameterized queries or prepared statements for every database call — never build SQL by concatenating user input into a query string.
Weekly security research

New vulnerability playbooks, tool updates, and bug bounty insights - delivered to your inbox. No spam.

Unsubscribe anytime. We respect your inbox.
Press ⌘K to search×