Calendar 07.05.2021

When building WordPress themes or plugins, sanitizing user input is essential for security. But sometimes, you need to sanitize content without stripping all the HTML, especially if you’re allowing trusted users (like admins or editors) to format content using safe HTML tags like <strong>, <a>, or <code>.

sec

In this tutorial, you’ll learn how to sanitize WordPress content while preserving safe HTML, using built-in WordPress functions.

🔐 Why You Need to Sanitize (But Keep HTML)

  • Prevent XSS (Cross-site Scripting) attacks
  • Allow users to format posts, bios, or inputs safely
  • Avoid breaking content by stripping valid tags

WordPress provides several sanitization and escaping functions—some remove all HTML (like sanitize_text_field()), while others let you define which tags are safe.

✅ Recommended Function wp_kses()

This is the key function for keeping safe HTML and removing anything dangerous.

$allowed_tags = array(
    'a' => array(
        'href' => true,
        'title' => true,
        'target' => true,
        'rel' => true
    ),
    'strong' => array(),
    'em' => array(),
    'code' => array(),
    'pre' => array(),
    'br' => array(),
    'p' => array(),
    'ul' => array(),
    'ol' => array(),
    'li' => array()
);

$clean_content = wp_kses( $user_input, $allowed_tags );

🧼 What it does:

  • Keeps only the tags you allow (like <a>, <strong>, etc.)
  • Strips out scripts, inline styles, or unwanted attributes

🛡️ Bonus: Use wp_kses_post() for WordPress Editor-Like Safety

WordPress also provides a helper function that mimics the default HTML allowed in the block editor or classic editor:

$clean_content = wp_kses_post( $user_input );

This is great for:

  • Sanitizing post content
  • User-submitted comments or bios (trusted roles)
  • Custom post meta that supports formatting

✍️ Use Case Example: Sanitizing a Custom Field with HTML

Let’s say you have a user-submitted bio field in a user profile form:

if ( isset( $_POST['bio'] ) ) {
    $sanitized_bio = wp_kses_post( $_POST['bio'] );
    update_user_meta( $user_id, 'bio', $sanitized_bio );
}

This lets users include basic formatting like <strong> or <a> but prevents script injection or unsafe HTML.

❌ What Not To Use (If You Want to Keep HTML)

  • sanitize_text_field() → Strips all HTML
  • esc_html() → Converts < and > to entities (no HTML output)
  • strip_tags() → Removes everything inside angle brackets

Use these only when you want plain text output.

✅ Quick Summary

FunctionKeeps HTML?Best Use
sanitize_text_field()❌ NoPlain text inputs
wp_kses()✅ Yes (custom tags)Fine-tuned sanitizing
wp_kses_post()✅ Yes (WordPress default tags)User-generated post content
esc_html()❌ NoDisplay only, escape for output
strip_tags()❌ NoHard strip of all tags

🎯 Final Thoughts

When dealing with user input in WordPress, security should always come first—but that doesn’t mean you have to sacrifice flexibility. With functions like wp_kses() and wp_kses_post(), you can sanitize safely while still allowing meaningful HTML formatting.

This is perfect for custom fields, user bios, comments, or any feature that enhances your UX through rich text.