principlejavascriptCritical
Output Encoding for Safe Rendering in Templates
Viewed 0 times
output encodingescapingxss preventionauto-escapetemplatedompurifysanitization
Problem
Rendering user-supplied data in HTML without encoding allows stored and reflected cross-site scripting. Browsers interpret unescaped user content as executable markup.
Solution
Use framework-provided auto-escaping in templates. In React, render user data as text content via JSX expressions—the framework HTML-encodes values automatically. For server-side templates, ensure auto-escaping is enabled.
Why
Auto-escaping converts characters like angle brackets, quotes, and ampersands into their HTML entity equivalents. Browsers display these as text rather than parsing them as markup or script.
Gotchas
- Bypassing framework escaping (via methods that set raw HTML) re-introduces XSS—avoid these methods with user-supplied data
- Encoding context matters: HTML encoding is not sufficient inside JavaScript string contexts or URL attributes—use the correct encoding function for each context
- User-supplied URLs in href attributes must be validated to reject javascript: URIs even after HTML encoding
- Rich text editors produce HTML output—sanitize it with a library like DOMPurify before storing or rendering, and use an allowlist of safe tags and attributes
Code Snippets
Safe rendering in React JSX and rich text sanitization
import DOMPurify from 'dompurify';
// Safe: JSX auto-encodes user data as text
function UserProfile({ user }) {
return (
<div>
<h1>{user.name}</h1> {/* auto-encoded */}
<p>{user.bio}</p> {/* auto-encoded */}
</div>
);
}
// For rich text from a WYSIWYG editor — sanitize before rendering
function RichContent({ htmlContent }) {
const clean = DOMPurify.sanitize(htmlContent, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br', 'ul', 'ol', 'li', 'a'],
ALLOWED_ATTR: ['href', 'title'],
FORBID_ATTR: ['style', 'onerror', 'onload']
});
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}Revisions (0)
No revisions yet.