Javascript 向wordpress post添加bookmarklet

Javascript 向wordpress post添加bookmarklet,javascript,wordpress,header,xss,bookmarklet,Javascript,Wordpress,Header,Xss,Bookmarklet,我正试图在我的WordPress站点上的帖子中添加一个javascript书签链接。然而,它不会在后期预览中发布。当我检查WordPress添加到帖子中的链接时,它已将其转换为javascript:void(0)。这个简单的例子再现了这个问题 <a href="javascript:alert('Alert!');">Search Scholar</a> 还有其他一些人也有同样的问题,但是除了给人们提供bookmarklet代码以供复制、粘贴和创建自己的bookma

我正试图在我的WordPress站点上的帖子中添加一个javascript书签链接。然而,它不会在后期预览中发布。当我检查WordPress添加到帖子中的链接时,它已将其转换为
javascript:void(0)
。这个简单的例子再现了这个问题

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

还有其他一些人也有同样的问题,但是除了给人们提供bookmarklet代码以供复制、粘贴和创建自己的bookmarklet之外,似乎没有人找到解决方案

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


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

最初的问题当然是由于:

如果没有特殊的WordPress,JavaScript无法添加到帖子内容中 移除过滤器的插件,该过滤器可防止 发布内容区域,以保护用户

要避免安装插件,可以使用建议的方法:

向WordPress添加JavaScript的安全推荐方法 生成的页面和WordPress主题或插件是通过使用
wp\u enqueue\u script()
。此函数包括脚本(如果没有) 已经包含,并且安全地处理依赖项

以下是有关
wp\u enqueue\u script()的所有详细信息。

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

您可以在该文件中创建一个函数,例如,将bookmarklet链接作为参数,并将
文档写入当前位置(或将节点作为子节点附加到已知元素)

然后包括脚本并在post中调用函数,如下所示:

<script type="text/javascript" src="/scripts/myscript.js"></script>
<script type="text/javascript">
<!--
bookmarklet(myLink);
//--></script>
或者,如果上述方法不起作用:

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

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

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


原始帖子(描述了如何在将帖子保存为非管理员用户时阻止WordPress剥离
javascript:
链接,我认为原始问题可能是这样的)

看起来WordPress在
content\u save\u pre
过滤器中删除了HTML。具体来说,它调用
wp includes\kses.php
中的
wp\u kses\u bad\u协议
方法:

/**
 * 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;
}

增强此方法安全性的一种方法是添加对特定用户或特定角色的检查(默认情况下,此筛选器实际上不在管理帐户上运行,因此您可以作为管理员使用
javascript:
指向您内心内容的链接)在允许使用
javascript
协议之前。

我从未使用过WordPress,但我的第一反应是在代码中搜索“void(0)”。你确定是Chrome去除了它而不是WordPress吗?你只在Chrome中看到这种行为吗?其他浏览器(IE8+,可能是其他浏览器)都理解这个标题,尽管没有规范说明我能找到它应该做什么。Chrome可能是唯一一个将javascript从bookmarklet中剥离出来的浏览器,但我可以想象,当该标题启用时,它们都会从发布的数据中剥离javascript。感谢您提供的信息,+1,尽管我觉得这还不能回答这个问题。你知道有一个插件已经存在了吗?我宁愿不去黑客对我自己的主题只是能够添加一个书签链接到我的一个可湿性粉剂帖子。您是否建议使用类似于
的东西和一些包含在执行
$([data bookmarklet]”中的JS。每个(function(){this.href='javascript:'+$(this.data('bookmarklet');})在帖子正文中?你能给我们一些更好的步骤来创建这个插件/解决这个问题吗?@gnarf在我回答之前,我实际上正在寻找一个插件来完成这个任务,但找不到任何插件。我确实找到了一些通用插件来共享页面/帖子,但没有任何可以用自己的链接/脚本进行自定义的插件。我曾考虑在我自己的WP博客上做一个演示,但我今天做不到。明天某个时候,我会尝试用一个示例和演示更新我的答案。也就是说,如果是这样的话,不能做到这一点(至少在帖子级别,没有插件,没有配置方法)也是一个答案。谢谢你的承诺!我可以通过以下步骤实现的一个答案是
/**
 * 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;
}
add_filter( 'kses_allowed_protocols', function ($protocols) {
   $protocols[] = 'javascript';
   return $protocols;
});