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_session

This 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.example

The 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: &lt;script&gt;alert(1)&lt;/script&gt;</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.