6

我正在尝试在我的 WordPress 网站上的帖子中添加一个 javascript 书签链接。但是,它不会在帖子预览中出现。当我检查 WordPress 添加到帖子中的链接时,它已将其转换为javascript:void(0). 这个简单的例子重现了这个问题。

<a href="javascript:alert('Alert!');">Search Scholar</a>

还有一些其他人在此处此处此处此处遇到了同样的问题,但似乎没有人找到解决方案,而不仅仅是提供他们的书签代码供人们复制和粘贴并创建自己的书签。

此问题的原因是 Chrome 的 XSS 保护在通过 wp-admin 提交链接时从链接中删除了 javascript。一种“解决方案”是将行添加header("X-XSS-Protection: 0");到根文件夹中的 wp-blog-header.php 。这是不安全的,因为它关闭了 WordPress 网站上的 XSS 保护,但它确实允许在页面加载时呈现小书签代码。

是否有任何不涉及关闭 XSS 保护的问题的真正解决方案?是否有一个插件可以安装到我的 WordPress 以允许我javascript:在帖子中添加链接?

4

2 回答 2

5

编辑 2经过更多研究,这实际上是由 OP 提到的浏览器的 XSS 检测引起的(与任何 WordPress 特定的功能相反)。问题仅在您单击PreviewWordPress 中的按钮时出现,并且仅在初始页面加载时出现。显然,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协议之前。

于 2013-11-12T05:09:19.800 回答
3

最初的问题当然是由于这个:

如果没有特殊的 WordPress 插件,JavaScript 无法添加到帖子内容中,该插件会删除过滤器,以防止帖子内容区域内出现不需要的代码以保护用户。

为避免安装插件,您可以使用推荐的方法:

将 JavaScript 添加到 WordPress 生成的页面和 WordPress 主题或插件的安全且推荐的方法是使用 wp_enqueue_script(). 如果尚未包含该脚本,则此函数将包含该脚本,并安全地处理依赖项。

以下是所有详细信息wp_enqueue_script()
http ://codex.wordpress.org/Function_Reference/wp_enqueue_script

然后,您需要创建一个自定义 JavaScript 文件,将其包含并注册您的帖子所需的功能。

您可以在该文件中创建一个函数,例如将您的书签链接作为参数,document.write并对当前位置执行(或将节点作为子节点附加到已知元素)。

然后包含脚本并在帖子中调用函数:

<script type="text/javascript" src="/scripts/myscript.js"></script>
<script type="text/javascript">
<!--
bookmarklet(myLink);
//--></script>

您只需要在同一篇文章中链接脚本 - 如果您在每篇文章中都使用此脚本,最好将其链接到标题中(header.php模板文件,在元标记和样式表链接之间)。

<script type="text/javascript" src="/scripts/myscript.js"></script>

或者,如果上述方法不起作用:

<script type="text/javascript" src="<?php bloginfo('template_url'); ?>/pathto/myscript.js"></script>

另请注意,如果该src属性被剥离,您需要转到仪表板中的用户和个人选项以关闭富编辑器。

有关如何在全球和帖子中在 WordPress 中使用 JavaScript 的来源和更多信息:http:
//codex.wordpress.org/Using_Javascript#Javascript_in_Posts

于 2013-11-11T19:26:22.497 回答