标注的博客| 安全研究| 渗透测试| APT

首页

精选 flexport 在 hackerone 这一年 6 个有趣的安全漏洞

作者 cayo 时间 2020-03-18
all

译者:Serene原文:Six Security Vulnerabilities from a Year of HackerOne 一年前,我们推出了在 HackerOne 上的赏金计划,以提高 Flexport 的安全性。 HackerOne 让我们为业余爱好者和专业渗透测试人员提供赏金来鼓励他们发现漏洞。 于是,我们收到了近 200 份报告,包括将服务器 token 从 nginx header 中删除 到 XSS 漏洞。 以下是 200 个报告中最有趣的 6 个漏洞。 1. 删除按钮中的XSS漏洞 当发起赏金计划时,我们没想到会收到有关 XSS 的有效报告,毕竟 React 中内置了防范这种漏洞的保护措施,不幸的是,我们收到的第一份不同寻常的报告就是关于存储型 XSS 漏洞的。 原因 当时我们在使用 Bootbox 来显示错误消息并创建确认对话框。 Bootbox 独立于 React 管理 DOM 元素,因此不受 React 的 XSS 保护措施的影响。 所以,当将用户输入直接展示在确认对话框中时,就触发了攻击。 修复 短期的修复方案是在用户输入传递给 Bootbox 展示之前,将所有可能和 XSS 相关的标签删除(JSXSS 提供了一个节点模块让这部分变得很简单)。正在筹备长期的解决方案是,从 Bootbox 转移到一个基于 React 的确认模块。 教训 React 阻止了 XSS 不代表所有代码都是安全的。对所有在 React 之外工作的库都不能信任,并且要尽可能地避免使用它们。 2. Markdown 渲染中的 XSS 漏洞 在修复了 Bootbox 并检查了我们其它类似的库之后,我们收到了第二个 XSS 漏洞报告——这次存在于我们的 Markdown 渲染中。 原因 我们的文本框中以 <div dangerouslySetInnerHtml={{__html: marked(text)}} /> 方式支持 Markdown,回想起来,这是一个坏主意。

<div dangerouslySetInnerHtml={{__html: marked(text)}} />
修复 将所有传递到 dangerouslySetInnerHtml 的文本都使用 XSS 过滤器,并创建一个 Lint 规则以在将来执行此操作。
dangerouslySetInnerHtml dangerous

3. Target=“_blank” 在所有从 HackerOne 中收到的报告中,最令人惊讶的是标准 HTML 标签的正常使用。 原因 当你用新标签页打开一个链接(<a target="_blank">),新打开的标签页可以利用 window.opener 属性访问初始标签并改变它的 location 对象。攻击者可以将原始页面设置为登录页面或其他任何内容。只能将 rel="noopener noreferrer" 添加到 a 标签中,来减轻这一类问题。

<a target="_blank"> rel="noopener noreferrer" a
修复 通过在使用 target="_blank" 时增加 rel="nofollow me noopener noreferrer",我们修复了该问题,这样新窗口就不能改变原始窗口的内容。另外,我们 向 ESLint 提交了一个 Lint 规则,防止以后大家犯同样的错误。
target="_blank" rel="nofollow me noopener noreferrer" def check_request_and_redirect_to_verify_token ... id = warden.session(resource_name)[:id] warden.logout warden.reset_session! session["#{resource_name}_id"] = id ... redirect_to verify_authy_path_for(resource_name) end

理论上说,这个代码在用户成功登录后会将其登出,并重新定向到第二重身份验证页面。 然而实际上,Devise 调用 authenticate? 检查用户是否进行了身份验证(在此处的代码之后运行):

authenticate? def authenticate?(*args) result = !!authenticate(*args) # Try to log the user in yield if result && block_given? result end

这会让用户重新登录。 修复 将 warden.logout 行更改为 sign_out 可以解决这个问题,因为 sign_out 有其他代码来清除登录。 我们在本地解决了这个问题,并向 Authy 提出了一项请求,以便能帮助大家解决问题。

warden.logout sign_out sign_out
教训 连信誉良好的安全公司有时也会出错,并且渗透测试也没有好的替代品。 对我们来说,最经济有效的方法仍然是 HackerOne。 我们发现这些报告对 Flexport 和我们的安全都具有很高的价值。 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/358/