Automattic\WooCommerce\EmailEditor\Integrations\Utils
Html_Processing_Helper::validate_caption_attribute │ public static │ WC 1.0
Validate and sanitize specific caption attributes for security.
Method of the class: Html_Processing_Helper{}
No Hooks.
Returns
null. Nothing (null).
Usage
$result = Html_Processing_Helper::validate_caption_attribute( $html, $attr_name ): void;
- $html(WP_HTML_Tag_Processor) (required)
- HTML tag processor.
- $attr_name(string) (required)
- Attribute name to validate.
Html_Processing_Helper::validate_caption_attribute() Html Processing Helper::validate caption attribute code
WC 10.4.3
public static function validate_caption_attribute( \WP_HTML_Tag_Processor $html, string $attr_name ): void {
$attr_value = $html->get_attribute( $attr_name );
if ( null === $attr_value ) {
return;
}
// Block all event handler attributes (on*) - Critical security fix.
if ( str_starts_with( $attr_name, 'on' ) ) {
$html->remove_attribute( $attr_name );
return;
}
switch ( $attr_name ) {
case 'href':
// Only allow http, https, mailto, and tel protocols.
if ( ! preg_match( '/^(https?:\/\/|mailto:|tel:)/i', (string) $attr_value ) ) {
$html->remove_attribute( $attr_name );
break;
}
// Sanitize and normalize the URL using WordPress's esc_url_raw.
$sanitized_url = esc_url_raw( (string) $attr_value );
if ( empty( $sanitized_url ) ) {
// If esc_url_raw returns empty, the URL was invalid - remove the attribute.
$html->remove_attribute( $attr_name );
} else {
// Set the attribute to the sanitized/normalized value.
$html->set_attribute( $attr_name, $sanitized_url );
}
break;
case 'target':
// Allow only common safe targets.
$allowed_targets = array( '_blank', '_self' );
$target_value = strtolower( (string) $attr_value );
if ( ! in_array( $target_value, $allowed_targets, true ) ) {
$html->remove_attribute( $attr_name );
} elseif ( '_blank' === $target_value ) {
// When target is "_blank", ensure rel attribute has noopener and noreferrer.
$current_rel = $html->get_attribute( 'rel' );
$rel_value = is_string( $current_rel ) ? $current_rel : null;
$normalized_rel = self::normalize_rel_attribute( $rel_value, true );
$html->set_attribute( 'rel', $normalized_rel );
}
break;
case 'rel':
// Normalize rel attribute: lowercase, deduplicate, preserve safe tokens.
$rel_value = is_string( $attr_value ) ? $attr_value : null;
$normalized_rel = self::normalize_rel_attribute( $rel_value, false );
if ( empty( $normalized_rel ) ) {
$html->remove_attribute( $attr_name );
} else {
$html->set_attribute( $attr_name, $normalized_rel );
}
break;
case 'style':
// Only allow safe CSS properties for typography and basic styling.
$safe_properties = self::get_safe_css_properties();
$sanitized_styles = array();
$style_parts = explode( ';', (string) $attr_value );
foreach ( $style_parts as $style_part ) {
$style_part = trim( $style_part );
if ( empty( $style_part ) ) {
continue;
}
$property_parts = explode( ':', $style_part, 2 );
if ( count( $property_parts ) !== 2 ) {
continue;
}
$property = trim( strtolower( $property_parts[0] ) );
$value = trim( $property_parts[1] );
// Only allow safe properties.
if ( in_array( $property, $safe_properties, true ) ) {
// Use centralized CSS value sanitization.
$sanitized_value = self::sanitize_css_value( $value );
if ( ! empty( $sanitized_value ) ) {
$sanitized_styles[] = $property . ': ' . $sanitized_value;
}
}
}
if ( empty( $sanitized_styles ) ) {
$html->remove_attribute( $attr_name );
} else {
$html->set_attribute( $attr_name, implode( '; ', $sanitized_styles ) );
}
break;
case 'class':
// Only allow alphanumeric characters, hyphens, and underscores.
if ( ! preg_match( '/^[a-zA-Z0-9\s\-_]+$/', (string) $attr_value ) ) {
$html->remove_attribute( $attr_name );
}
break;
case 'data-type':
case 'data-id':
// Only allow alphanumeric characters, hyphens, and underscores.
if ( ! preg_match( '/^[a-zA-Z0-9\-_]+$/', (string) $attr_value ) ) {
$html->remove_attribute( $attr_name );
}
break;
default:
// Handle data-* attributes with strict validation.
if ( str_starts_with( $attr_name, 'data-' ) ) {
if ( ! preg_match( '/^[a-zA-Z0-9\-_]+$/', (string) $attr_value ) ) {
$html->remove_attribute( $attr_name );
}
break;
}
// Default deny policy: Remove any attribute not explicitly allowed.
$html->remove_attribute( $attr_name );
break;
}
}