Skip to content
← Back to Functions
Code

HTML Content Policy Cleaner

Cleans a limited subset of HTML tags for trusted admin-authored content and removes common script/event-handler risks.

Function signature

ogCleanAllowedHtmlContent(html, allowed_tags = array())

Categories

  • Content Display

Parameters

htmlRaw HTML.allowed_tagsList of allowed tag names.

Return value

Short public-safe status message.

  • html
  • allowed_tags

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Cleans limited HTML content for trusted admin-authored content areas.
 *
 * This is a conservative helper, not a replacement for a full audited HTML sanitizer
 * when untrusted public users can submit rich HTML.
 *
 * @param string $html Raw HTML.
 * @param array $allowed_tags List of allowed tag names.
 * @return array Cleaned HTML and removed-risk metadata.
 */
function ogCleanAllowedHtmlContent($html, $allowed_tags = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$html = (string)$html;
	if (empty($allowed_tags)) {
		$allowed_tags = array('p', 'br', 'strong', 'em', 'ul', 'ol', 'li', 'blockquote', 'code', 'pre', 'a');
	}

	$allowed_map = array();
	foreach ($allowed_tags as $tag) {
		$tag = strtolower(trim((string)$tag));
		if (preg_match('/^[a-z0-9]+$/', $tag)) {
			$allowed_map[$tag] = true;
		}
	}

	$html = preg_replace('/<\s*(script|style|iframe|object|embed|form|input|button|meta|link)[^>]*>.*?<\s*\/\s*\1\s*>/is', '', $html);
	$html = preg_replace('/<\s*(script|style|iframe|object|embed|form|input|button|meta|link)[^>]*\/?>/is', '', $html);
	$html = preg_replace('/\s+on[a-z]+\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)/i', '', $html);
	$html = preg_replace('/\s+(href|src)\s*=\s*("|\')\s*javascript:[^"\']*("|\')/i', '', $html);

	$allowed_string = '';
	foreach (array_keys($allowed_map) as $tag) {
		$allowed_string .= '<' . $tag . '>';
	}

	$clean_html = strip_tags($html, $allowed_string);

	$result['success'] = true;
	$result['message'] = 'Allowed HTML content cleaned.';
	$result['data'] = array(
		'html' => $clean_html,
		'allowed_tags' => array_keys($allowed_map)
	);

	return $result;
}