编辑 2经过更多研究,这实际上是由 OP 提到的浏览器的 XSS 检测引起的(与任何 WordPress 特定的功能相反)。问题仅在您单击Preview
WordPress 中的按钮时出现,并且仅在初始页面加载时出现。显然,WordPress 会在请求标头中发送一些 HTML,这会触发浏览器中的 XSS 功能。如果加载预览,然后刷新页面,XSS 问题就会消失,并且javascript:
链接会在保存时显示。查看实际站点时,发布页面后,从未遇到过此 XSS 问题。
编辑经过一些更深入的研究(与@gnarf 合作),事实证明,实际问题归结为 WordPressjavascript:
在其预览功能中处理链接的方式。似乎 WordPress 有一些自定义 Javascript 可以运行并将所有javascript:
链接转换为javascript:void(0)
链接(删除任何自定义代码),但前提是您正在预览页面。发布页面后,javascript:
链接将正确呈现。
原始帖子javascript:
(描述了如何在将帖子保存为非管理员用户时阻止 WordPress 删除链接,这就是我认为最初的问题可能是什么)
看起来 WordPress 去除了content_save_pre
过滤器中的 HTML。具体来说,它调用以下wp_kses_bad_protocol
方法wp-includes\kses.php
:
/**
* Sanitize string from bad protocols.
*
* This function removes all non-allowed protocols from the beginning of
* $string. It ignores whitespace and the case of the letters, and it does
* understand HTML entities. It does its work in a while loop, so it won't be
* fooled by a string like "javascript:javascript:alert(57)".
*
* @since 1.0.0
*
* @param string $string Content to filter bad protocols from
* @param array $allowed_protocols Allowed protocols to keep
* @return string Filtered content
*/
function wp_kses_bad_protocol($string, $allowed_protocols) {
$string = wp_kses_no_null($string);
$iterations = 0;
do {
$original_string = $string;
$string = wp_kses_bad_protocol_once($string, $allowed_protocols);
} while ( $original_string != $string && ++$iterations < 6 );
if ( $original_string != $string )
return '';
return $string;
}
该$allowed_protocols
参数通过该wp_allowed_protocols()
方法检索,该方法将kses_allowed_protocols
过滤器应用于协议列表。
有了这些信息,您应该能够绑定kses_allowed_protocols
过滤器以添加javascript
为有效信息(请注意,这当然会引发安全问题):
add_filter( 'kses_allowed_protocols', function ($protocols) {
$protocols[] = 'javascript';
return $protocols;
});
增强此方法安全性的一种方法是添加对特定用户或特定角色的检查(默认情况下,看起来此过滤器实际上并未在管理帐户上运行,因此您可以使用javascript:
指向您的心脏内容的链接作为admin) 在允许javascript
协议之前。