User Tools

Site Tools


security_fundamentals:php_escaping_and_output_encoding

3. Escaping and Output Encoding — Keeping Untrusted Data in Its Place

Once untrusted data enters the system, it must be handled with care.
Validation shapes the data
— but escaping determines where that data is allowed to go.

Security is not just about rejecting bad input.
It’s about ensuring that even valid input cannot break out of its intended context.

This page introduces the mental model of contextual output encoding
— the quiet discipline that keeps untrusted data in its place.


1. Escaping Is About Context, Not Characters

Escaping is not a universal transformation.
It is a context‑specific contract
.

The same string must be escaped differently
depending on where it is placed:

  • HTML text
  • HTML attributes
  • JavaScript
  • CSS
  • URLs
  • SQL queries
  • shell commands
  • file paths

There is no “one escape to rule them all.”
Security comes from choosing the right encoding for the right context.


2. HTML Escaping — The Default for Web Output

When outputting untrusted data into HTML,
the safe default is to
escape:

<
>
&
"
'

This prevents:

  • HTML injection
  • broken markup
  • accidental tag creation
  • XSS payloads

Most template engines do this automatically.
Security comes from not disabling it.


3. Attribute Escaping — A Different Boundary

HTML attributes are a different context
with different risks.

Example:

<input value="<?= $escaped ?>">

Here, escaping must prevent:

  • breaking out of the attribute
  • injecting new attributes
  • injecting event handlers
  • closing the tag early

Attribute escaping is stricter than HTML escaping.
Treat it as a separate boundary.


4. JavaScript Escaping — The Most Dangerous Context

Never place untrusted data directly into JavaScript.

If you must, use:

  • JSON encoding,
  • strict escaping,
  • safe wrappers

Example:

<script>
    const data = <?= json_encode($safeData, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
</script>

This prevents:

  • string termination
  • code injection
  • XSS payloads
  • unexpected execution

JavaScript is the most fragile boundary.
Treat it with respect.


5. URL Encoding — Preventing Injection Through Navigation

URLs are another context entirely.

Example:

<a href="/search?q=<?= urlencode($query) ?>">

URL encoding prevents:

  • breaking query strings
  • injecting new parameters
  • altering navigation
  • redirect manipulation

Never concatenate untrusted data into URLs without encoding.


6. SQL Parameterization — Escaping Is Not Enough

SQL is not escaped — it is parameterized.

Example: code php> $stmt = $pdo→prepare('SELECT * FROM users WHERE email = ?'); $stmt→execute([$email]); </code> Parameterization prevents:

  • SQL injection
  • broken queries
  • type confusion
  • malicious operators

Escaping SQL manually is fragile and error‑prone.
Use parameters. Always.


7. Shell Escaping — Avoid It Entirely When Possible

Shell commands are extremely dangerous.

If you must use them:

  • escape arguments
  • avoid concatenation
  • use safe wrappers (escapeshellarg, escapeshellcmd)
  • prefer built‑in PHP functions instead

The safest shell command is the one you never run.


8. Template Engines — Trust the Defaults, Not the Exceptions

Most modern template engines:

  • escape HTML by default
  • escape attributes when needed
  • provide safe helpers
  • prevent accidental raw output
  • Security collapses when developers:
  • disable escaping
  • use “raw” output
  • bypass the template engine
  • mix PHP and HTML manually

Trust the defaults.
Avoid the escape hatches.


9. Escaping Complements Validation — It Does Not Replace It

Validation shapes the data.
Escaping keeps it in its lane.

You need both:

  • validation ensures the data is what you expect
  • escaping ensures the data stays where it belongs

Security is layered, not singular.


Summary

Escaping and output encoding are about context, not characters.

A secure system:

  • escapes based on where the data goes
  • treats HTML, attributes, JS, URLs, SQL, and shell as separate boundaries
  • uses parameterization for SQL
  • avoids raw JavaScript injection
  • trusts template engine defaults
  • never disables escaping without a clear reason

Security is not about distrusting the data
—it’s about respecting the boundaries.


This page describes secure defaults and common practices in modern PHP. It is not a complete security guide, and it does not replace formal audits or framework‑specific documentation. These principles are consistent enough to be useful, but security always requires context, judgment, and ongoing review.


security_fundamentals/php_escaping_and_output_encoding.txt · Last modified: by editor