Weakness reference
CWE-150

Improper Neutralization of Escape, Meta, or Control Sequences

This weakness occurs when software fails to properly handle or remove escape sequences, meta-characters, and control characters before passing data to another…

01Summary

This weakness occurs when software fails to properly handle or remove escape sequences, meta-characters, and control characters before passing data to another system or component. These special characters can be interpreted by the downstream system in unintended ways, potentially leading to command injection, format string attacks, terminal manipulation, or other security issues. Proper neutralization ensures that user-controlled data is treated as literal content, not as instructions.

02How It Happens

Many systems and protocols use special character sequences to control behavior—shell interpreters use backticks and $() for command substitution, terminal emulators interpret ANSI escape codes to change colors or cursor position, printf-style functions interpret %x and %n as format directives, and log parsers may misinterpret control characters. When an application accepts user input and passes it directly to one of these downstream components without neutralizing these sequences, an attacker can craft input containing escape or control characters that the downstream system will interpret as commands or directives rather than literal data. The vulnerability exists because the developer did not account for the special meaning these characters hold in the receiving context.

03Real-World Impact

Exploitation can lead to arbitrary command execution if escape sequences are passed to a shell, unauthorized information disclosure if format strings are injected into logging or output functions, terminal hijacking or denial of service if ANSI escape codes are sent to a terminal without filtering, or data corruption if control characters are written to structured files. The severity depends on the downstream component and the privileges under which it runs; command injection in a privileged context is critical, while terminal manipulation may be lower severity but still disruptive.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import subprocess
import sys

user_input = sys.argv[1]
# Directly pass user input to shell command
result = subprocess.run(f"echo {user_input}", shell=True, capture_output=True)
print(result.stdout.decode())

Why it's vulnerable:
The user input is interpolated directly into a shell command string without escaping or neutralizing special characters like backticks, $(), semicolons, or pipes. An attacker can inject shell metacharacters to execute arbitrary commands.

Fixed pattern
import subprocess
import sys

user_input = sys.argv[1]
# Pass user input as a separate argument, not as part of the command string
result = subprocess.run(["echo", user_input], capture_output=True)
print(result.stdout.decode())
Vulnerable pattern
<?php
$user_input = $_GET['message'];
// Directly pass user input to system command
$output = shell_exec("echo " . $user_input);
echo $output;
?>

Why it's vulnerable:
The user input is concatenated directly into a shell command without escaping. Special characters like backticks, $(), or semicolons will be interpreted by the shell as metacharacters, allowing command injection.

Fixed pattern
<?php
$user_input = $_GET['message'];
// Use escapeshellarg() to neutralize shell metacharacters
$safe_input = escapeshellarg($user_input);
$output = shell_exec("echo " . $safe_input);
echo $output;
?>

05Prevention Checklist

Avoid shell execution when possible.
Use language-native functions or libraries instead of passing data to shell interpreters (e.g., use subprocess.run() with a list of arguments instead of shell=True).
Use parameterized or list-based APIs.
When calling external processes, pass arguments as separate array/list elements rather than concatenating them into a single command string.
Escape or neutralize special characters for the target context.
If shell execution is unavoidable, use context-appropriate escaping functions (escapeshellarg() in PHP, shlex.quote() in Python).
Validate and allowlist input.
Restrict user input to known-safe character sets and patterns; reject anything containing control characters, escape sequences, or metacharacters if they are not expected.
Use allowlists for format strings and log output.
Never allow user input to directly control format string arguments; use fixed format strings and pass user data as arguments instead.
Test with special characters.
Include backticks, $(), semicolons, pipes, newlines, and ANSI escape codes in your test cases to verify they are handled safely.

06Signs You May Already Be Affected

Check your application logs for unexpected command execution, unusual process spawning, or error messages indicating shell syntax errors following user input submission. Review any code that constructs shell commands, system calls, or format strings by concatenating user-supplied data; if you find such patterns, they are likely vulnerable. If your application writes user input to terminal output or log files without filtering, search those logs for ANSI escape sequences (e.g., \x1b[) or other control characters that may indicate attempted terminal manipulation.

07Related Recent Vulnerabilities