Independent Editorial DeskWordPress Releases, Builds, and Operations
Back to Archive
Hardening NotesImplementation Notes

WordPress wp_kses Example: Allow Safe Custom HTML in Plugin Output

Use wp_kses with a narrow allowlist so plugin output supports limited formatting without trusting arbitrary HTML.

Published

April 24, 2026

Reading Time

2 min read

Updated

April 24, 2026

HTML sanitization flow showing WordPress filtering unsafe markup into a safe output.
Control LedgerHardening Notes

Hardening Notes

Baselines, access reduction, and default settings that stand up in production.

Best For

Teams preparing, launching, or maintaining WordPress as a backend service in a production stack.

Primary Topics

Hardening NotesImplementation Notes

Editorial Focus

Control Ledger: Baselines, access reduction, and default settings that stand up in production. Updated on April 24, 2026.

Full Report

Last reviewed: April 24, 2026

Escaping output is not enough when a plugin intentionally allows limited HTML. A callout component, notice banner, or custom field may need links, emphasis, and line breaks, but that does not mean arbitrary HTML should pass straight through.

This guide shows how to use wp_kses() to allow a small set of safe tags in plugin output without opening the door to script injection or sloppy markup rules.

Start with a narrow allowlist

<?php
function vulnwp_allowed_notice_html() {
	return array(
		'a' => array(
			'href'   => true,
			'target' => true,
			'rel'    => true,
		),
		'strong' => array(),
		'em'     => array(),
		'br'     => array(),
		'code'   => array(),
	);
}

The allowlist should describe exactly what the feature needs, not what HTML happens to be convenient to support today.

Sanitize before rendering

$raw_notice = get_option( 'vulnwp_notice_html', '' );

echo wp_kses( $raw_notice, vulnwp_allowed_notice_html() );

wp_kses() removes tags and attributes that are not in the allowlist. That gives you controlled formatting without trusting the stored HTML blindly.

Use wp_kses_post only when post-style content is expected

If the content is truly post-like and should allow the same HTML WordPress allows in post bodies, wp_kses_post() may be appropriate. For plugin options and admin-configured snippets, a custom allowlist is usually better because it is much smaller and easier to audit.

$safe = wp_kses_post( $raw_post_like_fragment );

That is broader than a custom allowlist, so use it only when the feature genuinely needs post-style markup.

Pair sanitization with admin guidance

If editors can enter allowed HTML, document the supported tags in the UI. That reduces confusion and prevents support tickets caused by stripped markup.

echo '<p class=\"description\">' . esc_html__( 'Allowed tags: a, strong, em, br, code.', 'vulnwp' ) . '</p>';

Production checklist

  • Prefer the smallest possible allowlist.
  • Sanitize at render time, even if the value was sanitized earlier.
  • Use esc_url() and targeted validation when link destinations have extra rules.
  • Document supported tags in the UI.
  • Do not allow style, script, or event handler attributes.
  • Review new tags before adding them permanently.

Common mistakes

  • Allowing too many tags. Bigger allowlists are harder to reason about.
  • Escaping and sanitizing interchangeably. They solve different problems.
  • Trusting saved admin content completely. Stored options can still be dangerous.
  • Allowing target without handling rel. External links need deliberate rules.
  • Using wp_kses_post() for tiny UI snippets. That is often broader than necessary.

Related reading

If the HTML appears inside a shortcode or widget output, pair this with the shortcode example. If the content is saved from an admin form, combine it with the admin_post handler guide once that flow exists in your plugin.

References and further reading

Popular Guides

Popular WordPress guides to read next.

These articles connect recurring production concerns: implementation details, updates, troubleshooting, recovery paths, and operational cleanup.

Continue Reading

More from the archive.

Diagnostic dashboard scene representing a WordPress Site Health review before major updates.
01Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Site Health Check Before Major Updates: What to Review First

A pre-update WordPress Site Health checklist covering loopbacks, connectivity, debug settings, and environment readiness.

Structured data and route review scene representing permalink validation after a WordPress migration.
02Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Permalink Checklist After Migration: Catch URL Problems Early

A post-migration WordPress permalink checklist for checking rewrite rules, post URLs, archives, and redirect noise.

Technical media workspace representing image preparation and optimization before upload to WordPress.
03Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Image Optimization Checklist: What to Fix Before Upload

A practical WordPress image optimization checklist covering dimensions, compression, formats, and Media settings before upload.