Escaping is the process of converting special characters into a representation that ensures they are interpreted as data, not executable code.
Example:
< → <
> → >
" → "
' → 'However, escaping is not universal. Each browser parser (HTML, JavaScript, CSS, URL, JSON) has different rules, meaning escaping must always be context‑specific.
2. Why Escaping Fails in Real Applications
A common but dangerous assumption is:
escape(userInput)Used everywhere.
This approach fails because:
- HTML escaping does not protect JavaScript
- JavaScript escaping does not protect URLs
- JSON escaping does not protect script execution
The browser does not see "escaped input", it sees syntax inside a specific parser.
3. HTML Body Context
Context
<div>USER_INPUT</div>Parser
HTML parser
Characters That Must Be Escaped
< > & " 'Secure Rendering
<script>alert(1)</script>Common Vulnerability
element.innerHTML = userInputThis causes the browser to re‑parse input as HTML, making escaping ineffective if done incorrectly.
4. HTML Attribute Context
Context
<input value="USER_INPUT">Parser
HTML attribute parser
Required Escaping
" ' < > &Why This Context Is Dangerous
Attributes can introduce new attributes or event handlers:
" autofocus onfocus=alert(1) x="If quotes are not properly escaped, the browser treats the input as HTML structure, not data.
5. JavaScript String Context
Single‑Quoted Strings
var data = 'USER_INPUT';Required Escaping
' \ newlineExample
\' \\ \nDouble‑Quoted Strings
var data = "USER_INPUT";Required Escaping
" \ newlineKey Point
Escaping must happen before JavaScript execution, not after rendering.
6. JavaScript Template Literals
Context
var data = `USER_INPUT`;Required Escaping
` \ $Additional Risk
Template literals allow expression evaluation:
${expression}This makes them extremely dangerous if user input reaches them unescaped.
7. JavaScript Execution Context (Critical)
Dangerous Sinks
eval()
new Function()
setTimeout(string)
setInterval(string)Example
eval('searchResults(' + responseText + ')');Why Escaping Does Not Work Here
JavaScript execution contexts cannot be safely escaped.
Correct rule:
NEVER eval user input8. JSON Context
Context
{"searchTerm":"USER_INPUT"}Required Escaping
" \ control charactersProper JSON Encoding
\" \\ \n \tCommon Anti‑Pattern
eval('callback(' + jsonResponse + ')')This converts JSON into JavaScript code, completely bypassing JSON safety guarantees.
9. URL Context
Context
<a href="USER_INPUT">Required Encoding
Percent‑encodingExample
%3A %2F %26 %3FCritical Mistake
HTML‑escaping URLs instead of URL‑encoding them.
10. JavaScript URL Assignment
Context
location.href = USER_INPUTWhy Escaping Is Not Enough
Certain schemes are executable:
javascript:
data:Correct defense:
Allow‑list http and https only11. CSS Context
Context
style="background: USER_INPUT;"Risks
CSS supports functions:
url()Legacy browsers support:
expression()CSS escaping is fragile and should be avoided for untrusted input.
12. DOM Insertion APIs
Dangerous APIs
innerHTML
outerHTML
document.write
insertAdjacentHTMLSafe Alternatives
textContent
innerText
setAttribute (with validation)13. Framework Escaping Pitfalls
React
JSX auto‑escapes by defaultDanger:
dangerouslySetInnerHTMLAngular
{{ value }}Danger when sanitization is bypassed.
Vue
v-htmlDirectly disables escaping.
14. A Generic Exploitation Thought Process (High‑Level)
1. Identify the rendering context
2. Identify escaping behavior
3. Determine the active parser
4. Understand how the browser interprets the data
5. Locate dangerous sinksThis is a mental model, not an exploit recipe.
15. Defensive Best Practices
ESCAPE BY CONTEXT
NEVER REUSE ESCAPERS
1. Identify the rendering context
2. Use the correct encoder
3. Avoid dangerous sinks
4. Validate before escaping
5. Prefer safe APIs16. Conclusion
Escaping is not a function.