将bookmarklet添加到wordpress帖子

时间:2013-11-07 19:14:05

标签: javascript wordpress header xss bookmarklet

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

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

还有一些人遇到了同样的问题herehereherehere,但似乎没有人找到解决方案除了给他们的书签代码供人们复制和粘贴并创建他们自己的书签。

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

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

2 个答案:

答案 0 :(得分:5)

EDIT 2 经过更多的研究,这实际上是由OP提到的浏览器的XSS检测引起的(与任何特定于WordPress的功能相反)。只有在WordPress中单击Preview按钮时才会出现此问题,并且仅在该初始页面加载时出现。显然,WordPress会在请求标头中发送一些HTML,并在浏览器中触发XSS功能。如果加载预览,然后刷新页面,XSS问题就会消失,javascript:链接会在保存时显示。在查看实际站点时,在发布页面后,永远不会遇到此XSS问题。

编辑经过深入研究(使用@gnarf)后,实际问题归结为WordPress在其预览功能中处理javascript:链接的方式。似乎WordPress有一些自定义Javascript可以运行并将所有javascript:链接转换为javascript:void(0)链接(删除任何自定义代码),但前提是您正在预览页面。发布页面后,javascript:链接将正确呈现。


原帖(介绍如何在以非管理员用户身份保存帖子时停止WordPress删除javascript:链接,这是我原先认为可能存在的问题)

看起来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:协议之前,您可以使用javascript指向管理员的心脏内容。

答案 1 :(得分:3)

最初的问题当然是由于:

  

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

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

  

向WordPress添加JavaScript的安全和推荐方法   生成的页面和WordPress主题或插件是使用   wp_enqueue_script()。如果没有,该函数包括脚本   已被包含在内,并安全地处理依赖关系。

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

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

您可以在该文件中创建一个函数,例如将您的bookmarklet链接作为参数,并将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