Wordpress变量$allowedposttags引发的一些问题

2020年10月03日 5768点热度 0人点赞 0条评论

一般不会碰到这东西, 也就是禁止评论里出现一些注入代码等等. 但是更改主题的时候, 发现Options Framework这个框架保存设置的时候, 对textarea标签进行过滤. 导致没办法添加一些标签, po个文记录一下.

第一趴

发现问题

想在主题中添加一个"额外代码"的选项, 可以把统计代码推送代码放到页脚. 原主题(kratos)也是有这个功能的. 但是实际使用遇到一些问题, Options Framework框架再保存设置的时候, 使用了 wp_kses 函数处理内容. 导致一些不在变量 $allowedposttags 中的标签无法显示.

/**
 * Sanitization for textarea field
 *
 * @param $input string
 * @return string $output sanitized string
 */
function of_sanitize_textarea($input)
{
    global $allowedposttags;
    return wp_kses($input, $allowedposttags);
}

add_filter('of_sanitize_textarea', 'of_sanitize_textarea');

百度现在是没有自动推送了, 最近更换域名也是重新开始对这些搜索引擎进行推送连接. 360搜索目前还支持自动推送, 加上代码后会有个奇怪的问题. 这段代码原本是这样的.

<script>
(function(){
var src = "https://jspassport.ssl.qhimg.com/11.0.1.js?d182b3f28525f2db83acfaaf6e696dba";
document.write('<script src="' + src + '" id="sozz"><\/script>');
})();
</script>

保存之后第四行id属性以及script标签结尾被删除了.

document.write('<script src="' + src + '">');

因为360这个推送代码id是有用的, 引入的第二个js文件调用这个id. 所以缺少了会报错, 并且标签尾没了浏览器会自动添加, 但是添加的很诡异, 会把他下面的所有内容全包进去.

提出方案

  • 删除框架中对textarea标签的验证
  • hook $allowedposttags, $allowedtags 使其支持scrtip标签和其ID属性
  • 更改js代码

第二趴

实际实施

第一种方法不可取, 虽然很简单, 直接return就行了. 但是毕竟这个框架这个函数不是只为这一个功能服务的. 而且这个验证还是挺有用的, 防止一些垃圾注入. 除非对自己的代码以及后期设置很有信心, 保证不会再代码安全上出现问题.

第二种方法就更危险了, 因为$allowedposttags 和 $allowedtags也不是为了这个函数专门创建的. 还对评论进行处理, 如果hook处理不当直接导致评论者可以通过评论漏洞来攻击服务器. 就算是加了is_admin()的判断, 也无法保证其他管理员都需了结代码安全问题.

提供的代码仅供参考, 再次强调: 此代码有一定风险, 谨慎使用.

/*
 * 只在后台页面hook允许script标签
 * 本意是可以让Options Framework设置保存验证允许保存带script标签的内容
 * */
if (is_admin()) {
    if (!function_exists('admin_allow_other_tag')) {
        function admin_allow_other_tag()
        {
            global $allowedposttags, $allowedtags;
            $allowedposttags["script"] = array('id' => true, 'src' => true);
            $allowedtags["script"] = true;
        }
    }
add_action( 'init', 'admin_allow_other_tag' );
}

第三种方法是我能想到的最好的解决办法了, 代码本意不就是引入个js么. 换种写法不就好了.

(function(){
let s = document.createElement('script');
s.id='sozz';
s.src="https://jspassport.ssl.qhimg.com/11.0.1.js?d182b3f28525f2db83acfaaf6e696dba"
document.body.appendChild(s);
})();

本来是想使用第二种方法的, 但是改了之后id标签等还是会被删除, 后来看了一些xss的文章, 发现这个验证还是非常有用的. 也就没有继续深究到底是因为什么id标签被删除了. 如果有同学直到可以告诉我.

感触颇深, MD这人真得学会变通. 就这个问题, 翻源码调试花了1个多小时(php技术不行), 最后想起来改js不就完了.

文章评论