Sabuj Kundu 17th Sep 2025

XSS (Cross-Site Scripting) is one of the most common web vulnerabilities, and WordPress provides built-in functions to protect against it.
The golden rule is simple: sanitize on input and escape on output.
In this guide, you’ll learn exactly how to sanitize, escape, and validate data in WordPress with code examples and best practices.

Sanitize vs Escape in WordPress

Sanitize/validate on input: clean and validate the data when you receive or store it (e.g. from $_POST, widget options, or REST API).
Escape on output: escape data when printing to HTML, attributes, JavaScript, or URLs.

Sanitization Functions (Input)

  • sanitize_text_field() – plain text, strips tags.
  • sanitize_email() – valid email format only.
  • sanitize_textarea_field() – for textarea-like input.
  • sanitize_file_name() – safe filenames.
  • sanitize_key() – identifiers like slugs or keys.
  • intval(), absint(), floatval() – numbers.
  • esc_url_raw() – sanitize URLs before saving.
  • wp_kses() – allow only specific HTML tags and attributes.
  • wp_kses_post() – HTML allowed in post content.
  • wp_strip_all_tags() – remove all HTML tags.

Escaping Functions (Output)

  • esc_html() – safe text inside HTML.
  • esc_attr() – safe inside attributes.
  • esc_url() – safe URLs.
  • esc_textarea() – inside <textarea>.
  • wp_kses(), wp_kses_post() – output with limited HTML allowed.
  • esc_js() (or better wp_json_encode()) – inside JavaScript.
  • wp_json_encode() – safely pass PHP data into JS.

Code Examples

Sanitize Form Input


if ( isset( $_POST['cbx_name'] ) ) {
    $name = sanitize_text_field( wp_unslash( $_POST['cbx_name'] ) );
    update_option( 'cbx_name', $name );
}
    

Escape Output


$name = get_option( 'cbx_name' );
echo '<p class="name">' . esc_html( $name ) . '</p>';
    

Escape Attributes and URLs


$link = get_option( 'cbx_link' );
echo '<a href="' . esc_url( $link ) . '" title="' . esc_attr( $name ) . '">' 
    . esc_html( $name ) . '</a>';
    

Allow Specific HTML


$allowed = array(
  'a' => array( 'href' => array(), 'title' => array() ),
  'strong' => array(),
  'em' => array(),
  'p' => array(),
);
$bio = wp_kses( $_POST['bio'], $allowed );
update_user_meta( $user_id, 'cbx_bio', $bio );
    

Extra Security Best Practices

  • Always use nonces (wp_nonce_field, check_admin_referer).
  • Check user capabilities with current_user_can().
  • Use prepared SQL with $wpdb->prepare().
  • Validate file uploads and sanitize filenames.
  • Audit third-party plugins and themes for XSS risks.

Quick Reference Cheat Sheet

  • Plain text → esc_html()
  • Attribute values → esc_attr()
  • URLs → esc_url()
  • JSON for JS → wp_json_encode()
  • Allowed HTML → wp_kses()
  • Sanitize text input → sanitize_text_field()
  • Sanitize URL before saving → esc_url_raw()
  • Numbers → absint(), intval()

By following these sanitization and escaping techniques, you can keep your WordPress plugins, themes, and custom code safe from XSS threats.