Weakness reference
CWE-138

Improper Neutralization of Special Elements

This weakness occurs when software fails to properly handle special characters or reserved words before passing data to another system or component. When…

01Summary

This weakness occurs when software fails to properly handle special characters or reserved words before passing data to another system or component. When untrusted input containing these characters reaches a downstream processor—a database, template engine, command shell, or markup parser—it can be misinterpreted as control instructions rather than literal data, leading to injection attacks.

02How It Happens

Most systems use special characters or keywords to denote structure and control: SQL uses quotes and semicolons, HTML uses angle brackets, shell commands use pipes and redirects, and so on. When user-supplied input is concatenated directly into a command, query, or markup without escaping or encoding those special characters, an attacker can craft input that "breaks out" of the intended data context and inject arbitrary instructions. The vulnerability arises because the downstream component cannot distinguish between data the developer intended and control syntax the attacker inserted.

The root cause is typically one of three patterns: concatenating user input into a command string instead of using parameterized/prepared constructs; failing to encode output for the specific context where it will be interpreted; or trusting input that should have been validated or sanitized. Different downstream systems require different neutralization strategies—SQL injection requires parameterized queries, XSS requires HTML entity encoding, command injection requires shell escaping or argument arrays—but the underlying principle is the same: special characters must be neutralized before they reach the interpreter.

03Real-World Impact

Successful exploitation can lead to unauthorized data access, modification, or deletion; account takeover; remote code execution; or complete system compromise depending on the downstream component and the attacker's intent. A SQL injection flaw might expose customer records; a command injection flaw might allow an attacker to read sensitive files or execute malware; an XSS flaw might steal session tokens or redirect users to phishing sites. The severity scales with the privileges of the affected component and the sensitivity of the data it controls.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import sqlite3

user_id = request.args.get('id')
query = "SELECT * FROM users WHERE id = " + user_id
cursor = sqlite3.connect(':memory:').cursor()
result = cursor.execute(query).fetchall()

Why it's vulnerable:
The user_id parameter is concatenated directly into the SQL query string. An attacker can supply id=1 OR 1=1 or id=1; DROP TABLE users;-- to alter the query's logic or structure.

Fixed pattern
import sqlite3

user_id = request.args.get('id')
query = "SELECT * FROM users WHERE id = ?"
cursor = sqlite3.connect(':memory:').cursor()
result = cursor.execute(query, (user_id,)).fetchall()
Vulnerable pattern
<?php
$username = $_GET['user'];
$query = "SELECT * FROM accounts WHERE username = '" . $username . "'";
$result = mysqli_query($connection, $query);
?>

Why it's vulnerable:
The $username variable is embedded directly into the query string without escaping. An attacker can supply user=' OR '1'='1 to bypass authentication or extract data.

Fixed pattern
<?php
$username = $_GET['user'];
$query = "SELECT * FROM accounts WHERE username = ?";
$stmt = mysqli_prepare($connection, $query);
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
?>

05Prevention Checklist

Use parameterized queries or prepared statements for all database interactions; never concatenate user input into query strings.
Apply context-specific output encoding: HTML entity encoding for web pages, URL encoding for URLs, shell escaping for system commands.
Validate input against a strict allowlist of expected formats (e.g., numeric IDs should match ^\d+$) before processing.
Use framework-provided escaping functions (wp_kses(), htmlspecialchars(), paramiko.SSHClient() argument lists) rather than manual string manipulation.
Apply the principle of least privilege: run database and system processes with minimal necessary permissions so injection has limited impact.
Regularly audit code for string concatenation patterns in security-sensitive contexts (queries, commands, template rendering).

06Signs You May Already Be Affected

Look for unexpected query results, unusual database activity, or error messages containing fragments of SQL or shell syntax in logs. Check for unexpected files or directories created by your web server process, or for admin accounts you did not create. Monitor for unusual outbound network connections or processes spawned by your application that you did not authorize.

07Related Recent Vulnerabilities