HackerOne | GitLab中Wiki页面存储型XSS

  • 2019 年 12 月 15 日
  • 筆記

漏洞信息

发现者:ryhmnlfj

漏洞种类:存储型xss

危害等级:高危

漏洞状态:已修复

前言

Ryhmnlfj发现GitLab的Wiki特定的分层链接Markdown存在存储型XSS漏洞。

漏洞再现

1、登录到GitLab

2.、打开您有权编辑Wiki页面的“项目”页面

3、打开Wiki页面

4、点击”New page” 按钮

5、Page slug项填写javascript:

6、点击” Create page”按钮

7、填写表单如下

Title: javascript; Format: Markdown Content: [XSS](.alert(1);)

8、点击” Create page”按钮

9、在创建的页面中点击”XSS”链接

单击创建页面中的“ XSS”链接后,将出现alert对话框

详细说明

GitLab应用程序将Markdown字符串.alert(1);转换为href属性javascript:alert(1);

在这种情况下,Wiki特定的Markdown字符串.转换为javascript:

漏洞影响

1、应过滤危险的链接属性javascript:alert(1);

2、提交一个安全的HTTP/HTTPS链接

附加信息

1、另一个特定Wiki的Markdown字符串..也会被转换为javascript:

2、使用标题字符串像javascript:STRING_EXPECTED_REMOVING也会重现此漏洞。例如,如果使用伪装的title字符串JavaScript::SubClassName.function_name创建一个这个wiki页面,则GitLab应用程序会将Wiki特定的Markdown字符串.转换JavaScript:

3、攻击者可以用各种方式来替换title字符串javascript: (例如data:, vbscript:, 等)

存在此漏洞的Gitlab版本信息为11.9.4-ee

附加影响

如果使用该漏洞创建的Wiki页面在“公共”项目中对所有人都是可见的(“ Wiki可见性”设置为“具有访问权限的所有人”),则可能有相当数量的GitLab用户和访问者单击恶意链接。

提交第一份报告后,我研究了后端源代码。结果,我发现了一些新东西,因此我发送了此附加报告。尽管您的缓解措施可能已经在进行中或已完成,但我希望此报告能帮助您进行审核和测试。

我研究的环境是GitLab Enterprise Edition的官方Docker安装11.10.4-ee

代码分析

在GitLab应用程序将Markdown文本转换为HTML Markup文本后,它将执行URI字符串重建和链接替换,作为Wiki特定的处理。问题在于此时没有对重构的URI字符串执行任何过滤。这是执行URI字符串重构的代码:

lib/banzai/filter/wiki_link_filter/rewriter.rb

def apply_rules            # Special case: relative URLs beginning with `/uploads/` refer to            # user-uploaded files will be handled elsewhere.            return @uri.to_s if public_upload?              # Special case: relative URLs beginning with Wikis::CreateAttachmentService::ATTACHMENT_PATH            # refer to user-uploaded files to the wiki repository.            unless repository_upload?              apply_file_link_rules!              apply_hierarchical_link_rules!            end              apply_relative_link_rules!            @uri.to_s          end            private            # Of the form 'file.md'          def apply_file_link_rules!            @uri = Addressable::URI.join(@slug, @uri) if @uri.extname.present?          end            # Of the form `./link`, `../link`, or similar          def apply_hierarchical_link_rules!            @uri = Addressable::URI.join(@slug, @uri) if @uri.to_s[0] == '.'          end

apply_hierarchical_link_rules!函数执行URL字符串重构。如果Title是JavaScript::ClassName.function_name并且内容是[XSS](.alert(1);),在wiki页面创建表单,@slug和@uri被Addressable::URI.join函数合并。

但是内部解析时Addressable::URI.join函数分别从@slug删除:ClassName.function_name,从@uri删除.(我在第一份报告中写到.被转换为JavaScript:,但实际上是分别从每个变量中删除了不必要的字符串。)

问题在于,对Addressable::URI.join函数重构的URI字符串未执行过滤。在这种情况下,apply_rules函数将按原样返回重构的URI字符串。并且此字符串用于链接替换。