Testing
The finale turns the course into practice: how to test for SQLi, how the standard tooling works, the broken-defence patterns to recognize, and a single deployable checklist that pulls all ten chapters together. (Test only systems you own or are authorized to assess.)
How to Test for SQLi
- Map every input that reaches a query — URL params, form fields, JSON bodies, headers, cookies — and remember stored values too (second-order, Chapter 6).
- Probe injectability — a lone
'(error/changed behaviour),' OR '1'='1vs' AND '1'='2(logic change), arithmetic like4+1in numeric params (Chapter 2). - Identify the context & type — string vs numeric (Ch. 2); in-band, blind, or out-of-band (Ch. 3) — this dictates the technique.
- Confirm impact safely — extract something harmless and unique (e.g.
@@version/version()), not destructive payloads, to prove the finding. - Check for blind — if no output/errors, test boolean (page difference) and time-based (
SLEEP) inference (Chapter 5).
information_schema, and dumps tables — and can escalate to reading files or OS commands where privileges allow. The lesson for defenders is sobering: everything attackers do in Chapters 2–6 is fully automated and requires no manual SQL. A single injectable parameter is, in practice, a one-command full-database disclosure. (Use sqlmap only against authorized targets / labs like PortSwigger, DVWA, Juice Shop.) Other tools: Burp Suite / OWASP ZAP scanners flag candidates; sqlmap confirms and exploits.
The Broken-Defence Catalogue
| Broken practice | Why it fails | Chapter |
|---|---|---|
| String-concatenated queries | the root cause — input parsed as SQL | 1, 2 |
| "We quote/strip quotes" | numeric context needs no quote; fragile escaping | 2 |
| Hiding DB errors as "the fix" | only downgrades error-based to blind | 3 |
| "No output, so it can't leak" | time-based blind works on identical responses | 5 |
| Validating only "user input" | second-order injection from stored data | 6 |
| String-formatting ≠ parameterizing | f-strings/template literals bake value into SQL | 7 |
| "Stored procedures are safe" | concatenating procs are still injectable | 8 |
| "We have a WAF" | bypassable; blind to second-order | 8 |
| "We use an ORM / NoSQL, so we're safe" | raw queries; operator injection | 9 |
The Hardening Checklist
$where; schema enforcementHow the Course Fits Together
The arc: understand the bug (Ch. 1 data-vs-code, Ch. 2 anatomy), the channels & techniques (Ch. 3 types, Ch. 4 union, Ch. 5 blind, Ch. 6 writes/stacked/second-order), then the defences — parameterized queries as the foundation (Ch. 7), defence in depth around it (Ch. 8), the realities of modern ORMs/NoSQL (Ch. 9), and operational testing/hardening (Ch. 10). It also pairs with the wider security set: SQLi and XSS are the two great injection bugs (database vs browser); Auth is what SQLi login-bypass attacks; and like all of them, the defence is a discipline applied everywhere, because the weakest query sets your exposure.
Hands-On Exercises
Write a SQLi test plan for a single endpoint: how you'd map inputs (including stored/second-order), probe injectability, identify context and type, and safely confirm impact. Explain what sqlmap automates and why "a single injectable parameter" is a serious finding.
📄 View solutionAudit this app against the broken-defence catalogue: it concatenates a numeric id, "strips single quotes" from inputs, hides DB errors, validates only request inputs (not stored data), uses a stored procedure that builds dynamic SQL, and relies on a WAF. List every flaw, its chapter, and the fix.
Produce a prioritized SQLi hardening plan for a new app (relational DB, an ORM, a couple of raw reporting queries, a search feature). Order the measures, justify the ordering, and explain how the one core principle (data vs code) unifies SQLi with XSS and connects to the Auth course.
📄 View solutionChapter 10 Quick Reference
- Test: map all inputs (incl. stored/second-order) → probe (
',OR 1=1, arithmetic) → identify context/type → confirm safely (version()) → check blind - sqlmap automates detect → type/context → DBMS fingerprint → enumerate schema → dump tables (→ files/OS where allowed); a single injectable param ≈ full-DB disclosure
- Broken defences: concatenation · quote-stripping · hiding errors · "no output" · validating only user input · string-formatting · "stored procs/WAF/ORM make us safe"
- Checklist: parameterize everything · allowlist identifiers · parameterize reads of own data · validate types · least privilege · generic errors · ORM raw audit · NoSQL type validation · WAF backstop · test
- The one principle: untrusted input stays data, never query code — parameterization sends query & data on separate channels
- Defence in depth reduces likelihood/blast radius; the load-bearing wall is parameterized queries
- Same principle as XSS (encode on output); SQLi & XSS are the two big injection families — database vs browser
★ SQL Injection Complete — 10 / 10 chapters
From data-vs-code foundations through injection anatomy, the in-band/blind/out-of-band types, union extraction, blind inference, writes/stacked/second-order, then the defences — parameterized queries as the one real fix, defence in depth, modern ORM/NoSQL realities, and a deployable testing & hardening checklist. Paired with HTTPS, CSRF, XSS, and Authentication, you now hold a five-course web-security set — and the unifying truth across all the injection bugs: keep untrusted input as data, never let it become code.