【问题标题】:Adding bookmarklet to wordpress post将书签添加到 wordpress 帖子
【发布时间】:2013-11-07 19:14:04
【问题描述】:

我正在尝试向我的 WordPress 网站上的帖子添加一个 javascript 小书签链接。但是,它不会在帖子预览中出现。当我检查 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 保护,但它确实允许在页面加载时呈现小书签代码。

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

【问题讨论】:

  • 我从未使用过 WordPress,但我的第一反应是在代码中搜索“void(0)”。
  • 您确定是 Chrome 将其剥离,而不是 Wordpress?您是否只在 Chrome 中看到这种行为?
  • 其他浏览器(IE8+,可能是其他浏览器)理解这个标头,尽管没有规范说明我可以找到它应该做什么。 Chrome 可能是唯一一个从小书签中去除 javascript 的工具,但我想它们都会在启用标头时从发布的数据中去除

标签: javascript wordpress header xss bookmarklet


【解决方案1】:

编辑 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-includes\kses.php中的wp_kses_bad_protocol方法:

/**
 * 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: 链接到您的心脏内容。

【讨论】:

  • 我的一部分有点喜欢最终的解决方案是从来没有真正的问题,只有“预览”显示了它。我希望这也能解决 OP 的问题......
  • 已确认,已解决。加载以前发布的页面的预览会显示javascript:void(0)。刷新预览页面后,代码如预期出现。很高兴我们找到了真相。
【解决方案2】:

最初的问题当然是因为这个:

如果没有特殊的 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

【讨论】:

  • 感谢您的信息,+1 虽然我觉得这不足以回答这个问题。您是否知道已经存在可以执行此操作的插件?我不想为了能够在我的一篇 wp 帖子中添加书签链接而对自己的主题进行黑客攻击。您是否建议可能像&lt;a href="#" data-bookmarklet="alert('boo')"&gt;bookmarklet&lt;/a&gt; 和一些包含在帖子正文中执行$("a[data-bookmarklet]").each(function() { this.href = 'javascript:' + $(this).data('bookmarklet'); }); 的JS?你能给我们一些更好的步骤来创建这个插件/解决这个问题吗?
  • @gnarf 在我回答之前我实际上正在寻找一个插件来执行此操作,但找不到任何插件。我确实找到了通用插件来共享页面/帖子,但找不到任何可以使用自己的链接/脚本自定义的地方。我正在考虑在我自己的 WP 博客上做一个演示,但我今天做不到。明天某个时候我会尝试用一个例子和演示来更新我的答案。话虽如此,如果 IMO 是这种情况,则无法做到这一点(至少在帖子级别,没有插件,没有配置方法)也是一个答案。
  • 感谢您的承诺!我可以通过遵循一些步骤来实现的答案是我希望看到的赏金。我觉得你可能知道如何把这个带回家并成为“将书签添加到 wp 帖子的指南”风格的答案(有或没有自定义插件):)
猜你喜欢
  • 1970-01-01
  • 2020-04-27
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多