当前位置:  开发笔记 > 编程语言 > 正文

将WMD编辑器的预览HTML与服务器端HTML验证对齐(例如,没有嵌入式JavaScript代码)

如何解决《将WMD编辑器的预览HTML与服务器端HTML验证对齐(例如,没有嵌入式JavaScript代码)》经验,为你挑选了1个好方法。

有许多Stack Overflow问题(例如,白名单,阻止XSS在C#WMD Markdown和服务器端使用WMD控制)关于如何对WMD编辑器生成的Markdown进行服务器端清理,以确保生成的HTML不包含恶意脚本,像这样:


但我也找不到在客户端插上漏洞的好方法.当然,客户端验证不能替代服务器上的擦除验证,因为任何人都可以伪装成客户端并发布令人讨厌的Markdown.如果你在服务器上清理HTML,攻击者就无法保存坏的HTML,因此以后没有其他人能够看到它并且他们的cookie被盗或被坏脚本劫持的会话.因此,有一个有效的案例可能不值得在WMD预览窗格中强制执行无脚本规则.

但想象一下,攻击者找到了将恶意Markdown放到服务器上的方法(例如,来自其他站点的受感染的源,或者在修复XSS错误之前添加的内容).将markdown转换为HTML时应用的服务器端白名单通常可以防止向用户显示错误的Markdown.但是,如果攻击者可以让某人编辑该页面(例如,通过发布另一个条目,说恶意条目有一个断开的链接并要求某人修复它),那么编辑该页面的任何人都会被劫持.这无疑是一个极端的案例,但它仍然值得防范.

此外,允许客户端预览窗口允许不同于服务器允许的HTML,这可能是一个坏主意.

Stack Overflow团队通过更改WMD来堵塞这个漏洞.他们是如何做到的呢?

[注意:我已经想到了这一点,但它需要一些棘手的JavaScript调试,所以我在这里回答我自己的问题,以帮助其他人可能想要做同样的事情].



1> Justin Grant..:

一种可能的解决方法是在pushPreviewHtml()方法中的wmd.js中.这是GitHub上来自Stack Overflow版本的WMD的原始代码:

if (wmd.panels.preview) {
    wmd.panels.preview.innerHTML = text; 
}

您可以使用一些清理代码替换它.这是对Stack Overflow 响应此帖的代码的改编,它限制了标签的白名单,对于IMG和A元素,限制为属性的白名单(并且也按特定的顺序!).请参阅Meta Stack Overflow帖子Stack Overflow,Server Fault和Super User上允许哪些HTML标记?有关白名单的更多信息.

注意:这个代码肯定可以改进,例如以任何顺序允许列入白名单的属性.它也不允许使用mailto:URL,这可能是Internet网站上的一件好事,但在您自己的Intranet站点上,它可能不是最好的方法.

if (wmd.panels.preview) {

    // Original WMD code allowed JavaScript injection, like this:
    //    
    // Now, we first ensure elements (and attributes of IMG and A elements) are in a whitelist,
    // and if not in whitelist, replace with blanks in preview to prevent XSS attacks 
    // when editing malicious Markdown.
    var okTags = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
    var okLinks = /^(]+")?\s?>|<\/a>)$/i;
    var okImg = /^(]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
    text = text.replace(/<[^<>]*>?/gi, function (tag) {
        return (tag.match(okTags) || tag.match(okLinks) || tag.match(okImg)) ? tag : ""
    })

    wmd.panels.preview.innerHTML = text;  // Original code 
}

另请注意,此修复程序不在GitHub上的WMD堆栈溢出版本中 - 显然更改是在稍后进行的,而不是检查回GitHub.

更新:为了避免破坏在键入URL时自动创建超链接的功能,您还需要对showdown.js进行更改,如下所示:

原始代码:

var _DoAutoLinks = function(text) {

    text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"$1");

    // Email addresses: 

    /*
        text = text.replace(/
            <
            (?:mailto:)?
            (
                [-.\w]+
                \@
                [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
            )
            >
        /gi, _DoAutoLinks_callback());
    */
    text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
        function(wholeMatch,m1) {
            return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
        }
    );

    return text;
}

固定代码:

var _DoAutoLinks = function(text) {
    // use simplified format for links, to enable whitelisting link attributes
    text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4");
    text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, '$1');
    return text;
}


是的,我不相信它也需要.也就是说,StackOverflow.com的人实现了这一点,以确保预览器永远不会生成他们的服务器端验证器不接受的HTML.虽然我同意不是一个非常重要的优先事项,但似乎是合理的.有关SO为什么这么做的详细信息,请参见http://meta.stackexchange.com/questions/1227/preview-should-match-the-posted-view.顺便说一下,我刚刚编辑了我的问题,以便与SO想要这样做的实际原因保持一致.
推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有