A05:2025 Injection
happens when untrusted input is executed by an interpreter as a command, query, or active content. The OWASP A05:2025 page covers SQL, NoSQL, OS command, ORM, LDAP, Expression Language, and XSS under this category.
The core danger of injection is that content the application received as “data” is interpreted by a downstream system as an instruction. That downstream system may be a database, shell, browser, template engine, LDAP server, XML parser, or expression language. Attackers usually do not rely on one special character alone; they study the context where input is used. Injection defense therefore depends on separating data from command structure, not merely blocking characters.
Root Cause
The root cause of injection is the failure to separate data from commands. When an application concatenates user input into a query, command, template, or HTML response, the interpreter may treat part of the input as structure.
SQL Injection Example
Vulnerable query:
query = "SELECT * FROM accounts WHERE customer_id = '" + request.args["id"] + "'"
rows = db.execute(query)Attack request:
GET /accounts?id=' OR '1'='1 HTTP/1.1
Host: vulnerable-app.example
Cookie: session=user_sessionThis payload changes the query logic and may return unauthorized records.
Parameterized safe approach:
query = "SELECT * FROM accounts WHERE customer_id = ?"
rows = db.execute(query, [request.args["id"]])Command Injection Example
Vulnerable code:
domain = request.args["domain"]
os.system("nslookup " + domain)Attack request:
GET /lookup?domain=example.com;id HTTP/1.1
Host: vulnerable-app.exampleThe safer approach uses an allowlist and argument arrays instead of passing shell strings:
domain = validate_domain(request.args["domain"])
subprocess.run(["nslookup", domain], shell=False, check=True)XSS Is Also Injection
XSS uses the browser as the HTML/JavaScript interpreter. If user input is written into HTML without context-aware encoding, the browser may execute it as script.
Vulnerable output:
<p>Search result for: <script>alert(1)</script></p>Defended output:
<p>Search result for: <script>alert(1)</script></p>Detection Approach
One payload is not enough to detect injection reliably. Understand which interpreter receives the input:
- SQL errors or response differences
- Time-based delay
- Boolean response differences
- Command output or timing
- HTML context changes
- Template errors
- LDAP filter behavior
- JSON or XML parser errors
Defensive Controls
- Use parameterized APIs for queries and commands.
- Do not concatenate shell strings.
- Apply context-aware output encoding.
- Use positive input validation.
- Avoid dynamic query concatenation even when using an ORM.
- Use parameterization inside stored procedures that build dynamic SQL.
- Add SAST, DAST, IAST, and fuzzing to CI/CD.
Blacklist-based character blocking is not a reliable injection defense by itself. The main goal is to prevent data from being interpreted as structure by the interpreter.