函数文档

wp_filter_oembed_result()

💡 云策文档标注

概述

wp_filter_oembed_result() 是一个 WordPress 过滤器函数,用于过滤和清理 oEmbed HTML 结果,以增强安全性。它主要针对非受信任提供商的 'rich' 和 'video' 类型响应,通过限制允许的 HTML 标签和属性来防止恶意代码注入。

关键要点

  • 函数用于过滤 oEmbed HTML,仅处理 'rich' 和 'video' 类型响应,其他类型直接返回原结果。
  • 如果 URL 来自受信任的 oEmbed 提供商(通过 WP_oEmbed::get_provider() 检查),则不修改 HTML,直接返回。
  • 对于非受信任提供商,使用 wp_kses() 严格限制允许的 HTML 标签和属性(如 a、blockquote、iframe 等)。
  • 函数通过正则表达式提取 iframe 内容,并添加数据秘密(data-secret)以增强安全性。
  • 返回过滤后的 HTML 字符串或 false(如果 iframe 不存在)。

代码示例

function wp_filter_oembed_result( $result, $data, $url ) {
    if ( false === $result || ! in_array( $data->type, array( 'rich', 'video' ), true ) ) {
        return $result;
    }

    $wp_oembed = _wp_oembed_get_object();

    // Don't modify the HTML for trusted providers.
    if ( false !== $wp_oembed->get_provider( $url, array( 'discover' => false ) ) ) {
        return $result;
    }

    $allowed_html = array(
        'a'          => array(
            'href' => true,
        ),
        'blockquote' => array(),
        'iframe'     => array(
            'src'          => true,
            'width'        => true,
            'height'       => true,
            'frameborder'  => true,
            'marginwidth'  => true,
            'marginheight' => true,
            'scrolling'    => true,
            'title'        => true,
        ),
    );

    $html = wp_kses( $result, $allowed_html );

    preg_match( '|(.*?)?.*()|ms', $html, $content );
    // We require at least the iframe to exist.
    if ( empty( $content[2] ) ) {
        return false;
    }
    $html = $content[1] . $content[2];

    preg_match( '/ src=(['"])(.*?)1/', $html, $results );

    if ( ! empty( $results ) ) {
        $secret = wp_generate_password( 10, false );

        $url = esc_url( "{$results[2]}#?secret=$secret" );
        $q   = $results[1];

        $html = str_replace( $results[0], ' src=' . $q . $url . $q . ' data-secret=' . $q . $secret . $q, $html );
        $html = str_replace( 'View all references View on Trac View on GitHub', '', $html );
    }
    return $html;
}

注意事项

  • 此函数在 WordPress 4.4.0 版本中引入,主要用于内部 oEmbed 处理,开发者通常不需要直接调用。
  • 安全过滤依赖于 wp_kses() 和正则表达式,确保只允许预定义的 HTML 结构,避免 XSS 攻击。
  • 如果 iframe 不存在于过滤后的 HTML 中,函数返回 false,可能导致嵌入失败。
  • 相关函数包括 WP_oEmbed::get_provider()、wp_generate_password()、wp_kses()、_wp_oembed_get_object() 和 esc_url(),用于支持功能实现。

📄 原文内容

Filters the given oEmbed HTML.

Description

If the $url isn’t on the trusted providers list, we need to filter the HTML heavily for security.

Only filters ‘rich’ and ‘video’ response types.

Parameters

$resultstring|falserequired
The oEmbed HTML result.
$dataobjectrequired
A data object result from an oEmbed provider.
$urlstringrequired
The URL of the content to be embedded.

Return

string|false The filtered and sanitized oEmbed result.

Source

function wp_filter_oembed_result( $result, $data, $url ) {
	if ( false === $result || ! in_array( $data->type, array( 'rich', 'video' ), true ) ) {
		return $result;
	}

	$wp_oembed = _wp_oembed_get_object();

	// Don't modify the HTML for trusted providers.
	if ( false !== $wp_oembed->get_provider( $url, array( 'discover' => false ) ) ) {
		return $result;
	}

	$allowed_html = array(
		'a'          => array(
			'href' => true,
		),
		'blockquote' => array(),
		'iframe'     => array(
			'src'          => true,
			'width'        => true,
			'height'       => true,
			'frameborder'  => true,
			'marginwidth'  => true,
			'marginheight' => true,
			'scrolling'    => true,
			'title'        => true,
		),
	);

	$html = wp_kses( $result, $allowed_html );

	preg_match( '|(<blockquote>.*?</blockquote>)?.*(<iframe.*?></iframe>)|ms', $html, $content );
	// We require at least the iframe to exist.
	if ( empty( $content[2] ) ) {
		return false;
	}
	$html = $content[1] . $content[2];

	preg_match( '/ src=(['"])(.*?)1/', $html, $results );

	if ( ! empty( $results ) ) {
		$secret = wp_generate_password( 10, false );

		$url = esc_url( "{$results[2]}#?secret=$secret" );
		$q   = $results[1];

		$html = str_replace( $results[0], ' src=' . $q . $url . $q . ' data-secret=' . $q . $secret . $q, $html );
		$html = str_replace( '<blockquote', "<blockquote data-secret="$secret"", $html );
	}

	$allowed_html['blockquote']['data-secret'] = true;
	$allowed_html['iframe']['data-secret']     = true;

	$html = wp_kses( $html, $allowed_html );

	if ( ! empty( $content[1] ) ) {
		// We have a blockquote to fall back on. Hide the iframe by default.
		$html = str_replace( '<iframe', '<iframe style="position: absolute; visibility: hidden;"', $html );
		$html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html );
	}

	$html = str_ireplace( '<iframe', '<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"', $html );

	return $html;
}

Changelog

Version Description
4.4.0 Introduced.