最近在为一家公司开发基于 Rails 的 Web 应用程序时,我不得不研究 XSS 漏洞。事实证明,在某些地方,应用程序可以采用 HTML 标记(例如,<script>jscodehere</script>
直接作为 GET 或 POST 请求中的参数。
然后可以通过应用程序的 params 哈希(所有传入键/值数据可从请求中获得的哈希)访问此参数。
现在,XSS 漏洞源于该站点还以 JSON 版本(例如/cart/1.json
)提供其许多页面的数据这一事实。
通过一些我不完全理解的机制(我想这在技术上是“反射型 XSS”?),<script>
然后进入 JSON 的未经清理的代码可以通过意外执行来破坏个人机器和其他站点。
我的问题是,为什么这不是一个选择加入系统?Rails 现在是第 4 版,所以我很惊讶仍然必须手动构建解决方案,但这适用于任何 Web 应用程序框架。默认情况下允许参数未经处理是一回事(也许 HTML 标签将用于用户的个人资料页面并且需要格式化)——我认为 Rails 也会对实际的渲染操作进行一些清理,从而限制输出,默认情况下,只有“安全”的 html 标签。
但是,在呈现 JSON 时,它没有进行这样的清理/清理,可能是因为当 JSON 响应被构建和解析时,它过于定制,无法这样做,但我不完全理解为什么
1) 一些内置机制没有到位
2)这没有被更多地讨论——我找不到关于在 web 上的 Rails 或 Sinatra 应用程序的 JSON 渲染中不安全传递 HTML/Script 标签的讨论(我只能找到关于清理 params 哈希的少量信息,因此在输入的过程中对值进行清理,这可以说更好,但可能不适用于所有情况,因为它是一种万能的解决方案;您可能希望保留一些 HTML 标记,但只去除标记<script>
,例如)。
3)为什么,至少在 Ruby 世界中,目前只有一个用于清理的库(Sanitize Gem,它实际上只适用于字符串数据类型——你必须编写自己的递归代码来清理哈希,就像参数哈希一样,似乎也没有任何东西写在上面!)。Rails 确实有一个内置的 sanitizer,但它被认为不如这个第三方 Sanitize Gem,并且在对消毒深度(一个字符串)有几个严格级别时不够灵活。
我是否误解了将 JSON 注入作为漏洞的有效性,还是因为 JSON 不是所有 Web 应用程序的核心功能而在很大程度上忽略了这个漏洞?
最终结果:我在后端的主应用程序控制器中使用了一个前置过滤器,以使用 Sanitize 库在每次请求传入时对 params 哈希进行清理。
但是,我相信这会显着减慢应用程序的速度,因为它必须在每个请求上发生,并且 Sanitizer 本质上是在哈希上以递归方式运行一系列正则表达式调用。这样一来,任何标签都不会进入数据库,也永远无法通过 JSON 提取出来,但在性能方面这是一个代价高昂的打击。有没有更好的办法?