Weakness reference
CWE-116

Improper Encoding or Escaping of Output

This weakness occurs when an application fails to properly encode or escape data before sending it to another component—such as a web browser, database, or…

01Summary

This weakness occurs when an application fails to properly encode or escape data before sending it to another component—such as a web browser, database, or command shell. Without proper encoding, untrusted data can be misinterpreted as code or control characters, allowing attackers to inject malicious instructions. This is one of the most common root causes of web vulnerabilities, including cross-site scripting (XSS) and SQL injection.

02How It Happens

When data flows from one component to another, the receiving component interprets it according to its own syntax rules. If the sender doesn't encode the data to match those rules, special characters in the data can be mistaken for syntax. For example, a < character in user input sent to an HTML page is interpreted as the start of a tag, not as literal text. Similarly, a single quote in a database query can prematurely close a string literal. The vulnerability arises when developers assume input is "safe" or forget that different contexts (HTML, JavaScript, SQL, URLs, shell commands) require different encoding schemes.

03Real-World Impact

Improper output encoding enables attackers to inject code that executes in unintended contexts. In web applications, this typically leads to cross-site scripting attacks where malicious scripts run in users' browsers, stealing session cookies or credentials. In database contexts, it can result in SQL injection, allowing unauthorized data access or modification. The severity depends on what the attacker can do with the injected code—from defacing a page to stealing sensitive information or taking over user accounts.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import sqlite3

user_input = request.args.get('search')
query = "SELECT * FROM products WHERE name = '" + user_input + "'"
cursor = sqlite3.connect(':memory:').cursor()
result = cursor.execute(query).fetchall()

Why it's vulnerable:
The user input is concatenated directly into the SQL query without escaping. An attacker can inject SQL syntax (e.g., ' OR '1'='1) to alter the query's logic.

Fixed pattern
import sqlite3

user_input = request.args.get('search')
query = "SELECT * FROM products WHERE name = ?"
cursor = sqlite3.connect(':memory:').cursor()
result = cursor.execute(query, (user_input,)).fetchall()
Vulnerable pattern
<?php
$user_input = $_GET['comment'];
echo "<div class='comment'>" . $user_input . "</div>";
?>

Why it's vulnerable:
User input is echoed directly into HTML without escaping. An attacker can inject HTML or JavaScript tags (e.g., <script>alert('xss')</script>) that execute in the browser.

Fixed pattern
<?php
$user_input = $_GET['comment'];
echo "<div class='comment'>" . esc_html($user_input) . "</div>";
?>

05Prevention Checklist

Use parameterized queries
for all database operations; never concatenate user input into SQL strings.
Encode output for its context
: use HTML entity encoding for HTML content, JavaScript escaping for JavaScript strings, URL encoding for URLs, and shell escaping for system commands.
Apply a whitelist approach
where possible—validate input against a known-good pattern and reject anything that doesn't match.
Use templating engines and frameworks
that apply context-aware encoding by default (e.g., Jinja2, Twig, Django templates).
Avoid eval() and similar functions
that interpret strings as code; use safer alternatives like JSON parsing or configuration libraries.
Test with special characters
during development—include <, >, ', ", ;, &, and other syntax characters in test cases.

06Signs You May Already Be Affected

Look for unexpected JavaScript execution in your pages (pop-ups, redirects, or console errors from unfamiliar scripts), unusual database queries in logs, or user-submitted content appearing in your HTML source code without angle brackets escaped. If you see <script> or event handlers like onclick= in user comments or profile fields, encoding is likely missing.

07Related Recent Vulnerabilities