$ cat owasp/a05.md
A05:2025
Injection
User input gets treated as code - by the database, the browser, the shell or a template.
## 1 · why it happens
Every injection bug has the same root cause: building a command by gluing strings together, so data and code end up in the same string. SQL injection, XSS, command injection and template injection are the same mistake in different interpreters.
The fix is also always the same idea: keep data separate from code - parameterised queries, output encoding, argument arrays instead of shell strings.
# JavaScript
// SQL injection
db.query(`SELECT * FROM users WHERE email = '${req.body.email}'`);
// Command injection
exec(`ping -c 1 ${req.query.host}`);
// XSS
el.innerHTML = 'Hello ' + params.get('name');db.query('SELECT * FROM users WHERE email = $1', [req.body.email]);
execFile('ping', ['-c', '1', req.query.host]); // no shell
el.textContent = 'Hello ' + params.get('name');# C#
var sql = $"SELECT * FROM Users WHERE Email = '{email}'";
var users = _db.Users.FromSqlRaw(sql).ToList();
Process.Start("cmd.exe", "/c ping " + host);var users = _db.Users
.FromSqlInterpolated($"SELECT * FROM Users WHERE Email = {email}")
.ToList(); // parameterised
Process.Start(new ProcessStartInfo("ping") { ArgumentList = { "-n", "1", host } });## 2 · how attackers find it from outside
| public source | what it tells them |
|---|---|
| Wayback Machine / search engines | Old URLs with parameters (?id=, ?search=, ?file=) - the inputs to test. |
| Error pages | A SQL error message after a single quote confirms the injection and names the database. |
| Tech discovery (headers, httpx) | Which template engine and database are used, so the attacker picks the right payload. |
→ all OSINT sources · run them on yourself
## 3 · how it's abused
⚠ Recon your own assets, or targets you have written permission to test. Passive OSINT reads public data, but using it to target someone else's systems can still be illegal or against their terms. Examples on this site use example.com placeholders.
' OR '1'='1SQLi: makes the WHERE clause always true - the classic login bypass.
'; WAITFOR DELAY '0:0:5'--Blind SQLi (SQL Server): if the response takes 5 seconds, the input reached the database.
<img src=x onerror=alert(1)>XSS: the image fails to load and the browser runs the attacker's JavaScript.
; idCommand injection: ends your command and runs a new one on the server.
{{7*7}}SSTI probe: if the page shows 49, the template engine is executing user input.
Payload examples adapted from PayloadsAllTheThings (MIT, © Swissky). Full lists:SQL Injection · XSS Injection · Command Injection · Server Side Template Injection · NoSQL Injection · Prompt Injection
## 4 · fix
- Parameterised queries / ORM methods. No string-built SQL.
- Encode output for its context (HTML, attribute, JS, URL). Prefer textContent and framework binding.
- Never pass user input to a shell - use argument arrays.
- Do not render user input as a template.
- Add a Content-Security-Policy as a second layer against XSS.
## 5 · detect
sqlmap
Detects and exploits SQL injection automatically.
authorized targets onlytest itZAP
Open-source web app scanner and proxy. The baseline scan is safe for CI.
authorized targets onlyfix at sourceBearer
Static analysis that follows sensitive data through your code.
Official description: OWASP A05:2025 Injection