Skip to content

SQL Injection (SQLi)

Prerequisites

  • INSECURE-threat-intel-app running locally (npm run docker:up in exercise-files/web-attacks-101/INSECURE-threat-intel-app).
  • Burp Suite Community configured per Burp Suite basics.
  • Sign in at http://localhost:8081 as analyst / projectx.

Ports

The lab app listens on host 8081. Burp’s default proxy listener (8080) does not conflict — you can use both at once without changing either port.

Likeliness meter

High — SQLi remains common in legacy apps, ad-hoc reporting queries, and ORMs used incorrectly.

Overview

SQL injection (SQLi) happens when an application builds a database query by stitching user input into the SQL string instead of sending input as bound parameters (prepared statements). The database cannot tell where the developer’s SQL ends and the attacker’s SQL begins.

From an attacker’s perspective, any field that influences a SELECT, INSERT, UPDATE, or DELETE is worth testing: search boxes, filters, sort keys, hidden form fields, JSON API properties, and login forms. Successful SQLi can mean authentication bypass, reading rows the user should not see, modifying or deleting data, and in worst cases command execution via database features.

In this app, vulnerable paths are Marketplace catalog search (/marketplace?q=) and the Threat Intelligence sign-in (POST /api/auth/login) — both concatenate user input into raw SQL.

Learning objectives

  1. Map the application in Burp and prioritize inputs that reach the database.
  2. Use error/boolean techniques to confirm injection before escalating impact.
  3. Demonstrate data disclosure and login bypass with captured requests.
  4. Document root cause and remediation in your lab report.

Attacker methodology

Work through the steps below in order. The goal is a short report you could hand to a developer: what is vulnerable, how you proved it, and what to fix.

Step 1 — Baseline the application in Burp

  1. Turn Intercept off (Proxy → Intercept).
  2. Browse the signed-in app: Dashboard, Marketplace, Documents, Tools, Settings.
  3. Open Proxy → HTTP history and skim new entries. You are building a mental (and Burp) site map of hosts, paths, and parameters.

Burp: Right-click interesting requests → Add to site map (or use the Target → Site map tab as traffic accumulates).

At this stage you are not attacking yet — you are learning what the app does when you click around.

Step 2 — Recon: look for database-backed inputs (and dead ends)

Attackers rarely get a labeled “SQLi here” button. They test anything that might become part of a query.

Area What you try In this lab
Dashboard panels Tamper with panel names or filters in Burp Synthetic read-only data — no user SQL; Repeater changes do not reveal injection
Search / login / filters Quotes, boolean logic This is where we focus next

Document in your head (or notes): “Dashboard looked normal; no obvious query errors.” That is realistic reporting.

Step 3 — Discover the lab surface

  1. Open http://localhost:8081/marketplace.
  2. In Burp HTTP history, find GET /marketplace requests that include a q parameter (catalog search).

You now have a candidate injection point: q in the catalog search.

Step 4 — Confirm injection with a single quote

  1. In the browser, search for a normal term: Threat.
  2. Note how many products return (likely one or two).

Burp:

  1. Find the GET /marketplace?q=Threat request in HTTP history.
  2. Send to Repeater (right-click → Send to Repeater).
  3. In Repeater, change q to a single quote: ' and Send.
  4. Compare the response to the benign search:
  5. More rows than expected, a database error in the body, or empty/error behavior all support “input reaches SQL.”

If the first quote is inconclusive, try test' and ' OR '1'='1 in Repeater — still on the same request line.

Step 5 — Prove impact: dump the product catalog (boolean / tautology)

In Repeater, set:

GET /marketplace?q=' OR '1'='1 HTTP/1.1

(or URL-encoded equivalent — Burp encodes when you type in the raw request line).

Send and verify the HTML lists all lab products (Threat Intel Pro, Feed Parser Add-on, etc.). You have shown the WHERE clause can be forced true — classic in-band SQLi / data disclosure.

Tidbit: ' OR 1=1-- variants are worth one Repeater attempt; different apps comment with --, #, or /*. This app is permissive with ' OR '1'='1.

Step 6 — Second vector: authentication bypass on app sign-in

The Threat Intelligence login at http://localhost:8081/login posts to POST /api/auth/login. Real engagements often have multiple SQL sinks — search on one page, login on another.

  1. Sign out if you are already authenticated.
  2. Submit a wrong password on the sign-in form — login should fail.
  3. In HTTP history, locate POST /api/auth/login.

Burp Repeater:

  1. Send the login POST to Repeater.
  2. Change the body to something like:
username=analyst'--&password=wrong
  1. Send. A 302 redirect to the dashboard (with session cookie set) means the password clause was commented out or bypassed — authentication bypass via SQLi. The dashboard may show the Found SQL Injection banner.

Valid lab credentials (for comparison): analyst / projectx.

Step 7 — Capture evidence for your report

In Burp, for each successful test:

  1. Right-click the Repeater request → Copy to file or note the raw request/response.
  2. Highlight the vulnerable parameter (q or username) and the observable impact (row count, login success).

Report checklist:

Field Your write-up
Affected URL /marketplace (q); POST /api/auth/login
Parameter q, username
Payload e.g. ' OR '1'='1, analyst'--
Impact Full product list disclosure; app login bypass
Root cause String concatenation into SQL (no prepared statements)
Remediation Parameterized queries; never embed raw input in SQL strings

Remediation

  • Use parameterized queries / prepared statements exclusively.
  • ORM: avoid raw query fragments with user input.
  • Least-privilege DB accounts; no DROP / dangerous stored procedures for app roles.
  • WAF is a compensating control only — fix the code path.