Skip to content

Escape Output

Cross-Site Scripting (XSS) is a security vulnerability where attackers inject malicious scripts into web pages viewed by other users. When a user visits the compromised page, the malicious script executes in their browser, potentially:

  • Stealing cookies and session tokens
  • Accessing sensitive page data
  • Performing actions on behalf of the user
  • Redirecting to malicious websites

Output escaping is the primary defense against XSS attacks. It converts dangerous characters (like <, >, ", ') in dynamic content into safe HTML entities before displaying them in web pages.

For example:

  • <script> becomes &lt;script&gt;
  • The browser displays the text instead of executing it as code

Output escaping prevents XSS attacks by ensuring that any dynamic content is treated as data, not executable code. This protection is essential because dynamic content can come from many sources that might contain malicious scripts.


Use htmlspecialchars() to escape HTML:

$userInput = "<script>alert('XSS!');</script>";
$safe = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
echo $safe;
// Displays: &lt;script&gt;alert(&#039;XSS!&#039;);&lt;/script&gt;
htmlspecialchars(
string $string, // The string to escape
int $flags = ENT_COMPAT, // How to handle quotes
?string $encoding = null, // Character encoding
bool $double_encode = true // Whether to encode existing entities
): string // Returns the escaped string

Parameters:

  • $string - The input string to escape
  • $flags - Controls quote handling:
    • ENT_QUOTES - Escapes both single and double quotes (recommended)
    • ENT_COMPAT - Only escapes double quotes (default)
    • ENT_NOQUOTES - Leaves quotes unescaped
  • $encoding - Character encoding (use 'UTF-8')
  • $double_encode - Set to false to avoid double-encoding existing entities

Always use these parameters:

  • ENT_QUOTES - Escapes both single and double quotes
  • 'UTF-8' - Proper character encoding

Different Contexts Need Different Escaping

Section titled “Different Contexts Need Different Escaping”
echo htmlspecialchars($userText, ENT_QUOTES, 'UTF-8');
<script>
var data = <?= json_encode($userText) ?>;
</script>
$url = "page.php?search=" . urlencode($userInput);

Don’t escape the same data twice:

// WRONG - double escaped
$escaped = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
$doubleEscaped = htmlspecialchars($escaped, ENT_QUOTES, 'UTF-8');
// CORRECT - escape once
echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
// User comment form
$comment = $_POST['comment'];
// Always escape before displaying
echo "<p>" . htmlspecialchars($comment, ENT_QUOTES, 'UTF-8') . "</p>";

Escape output, not input. Escape data right before displaying it, not when storing it in the database.