在 Node.js / 服务器端 javascript 中防止 XSS

Posted

技术标签:

【中文标题】在 Node.js / 服务器端 javascript 中防止 XSS【英文标题】:Preventing XSS in Node.js / server side javascript 【发布时间】:2011-04-11 22:42:03 【问题描述】:

知道如何防止对 node.js 应用程序的 XSS 攻击吗?任何处理在 href、onclick 属性等中删除 javascript 的库。来自 POST 数据?

我不想为所有这些写一个正则表达式:)

有什么建议吗?

【问题讨论】:

【参考方案1】:

我创建了一个捆绑 Caja html Sanitizer 的模块

npm install sanitizer

http://github.com/theSmaw/Caja-HTML-Sanitizer

https://www.npmjs.com/package/sanitizer

感谢任何反馈。

【讨论】:

使用require('sanitizer').sanitize 去除所有a[href] 属性,而不仅仅是顽皮的属性。对于我们的用例,我们需要链接仍然被接受(只是不是顽皮的链接,以及其他 xss 顽皮等),有什么建议吗?【参考方案2】:

Sanitize/Rewrite HTML on the Client Side 的答案之一建议从 Google Caja 借用 JS 中基于白名单的 HTML sanitizer,据我所知,它可以在不依赖浏览器 DOM 的情况下实现 HTML SAX 解析器.

更新:另外,请记住,Caja sanitizer 显然已经过全面、专业的安全审查,而众所周知,正则表达式很容易以危及安全的方式输入错误。

2017-09-24 更新:现在还有DOMPurify。我还没有使用它,但它看起来满足或超过了我寻找的每一点:

尽可能依赖运行时环境提供的功能。 (尽可能依赖经过充分测试的成熟实现,这对于性能和最大限度地提高安全性都很重要。)

依赖浏览器的 DOM 或 Node.JS 的 jsdom。

默认配置旨在尽可能少地剥离,同时仍保证删除 javascript。

支持 HTML、MathML 和 SVG 在 IE8 和 IE9 下回退到 Microsoft 专有的、不可配置的 toStaticHTML

高度可配置,使其适用于对可以包含任意 HTML 的输入实施限制,例如 WYSIWYG 或 Markdown 注释字段。 (其实这里是最上面的)

支持常用的标签/属性白名单/黑名单和 URL 正则表达式白名单 具有特殊选项可进一步清理某些常见类型的 HTML 模板元字符。

他们非常重视兼容性和可靠性

在 16 种不同浏览器以及 Node.JS 的三个不同主要版本上运行的自动化测试。 为确保开发人员和 CI 主机都在同一页面上,发布了锁定文件。

【讨论】:

谢谢,我基本上已经用正则表达式解决了(糟糕)——但我很想研究创建一个连接中间件来清理所有参数。【参考方案3】:

所有常用技术也适用于 node.js 输出,这意味着:

黑名单将不起作用。 您不应该为了保护 HTML 输出而过滤输入。它不会起作用,或者会通过不必要地畸形数据来起作用。 您应该在 HTML 输出中对文本进行 HTML 转义。

我不确定 node.js 是否为此提供了一些内置功能,但类似的东西应该可以完成这项工作:

function htmlEscape(text) 
   return text.replace(/&/g, '&').
     replace(/</g, '&lt;').  // it's not neccessary to escape >
     replace(/"/g, '&quot;').
     replace(/'/g, '&#039;');

【讨论】:

“你不应该过滤输入”...“你应该 HTML-escape...输出”:你对这个建议的最佳实践有任何参考吗? @DanielFlippance 这两点是“你应该对 HTML 输出进行 HTML 转义”的逻辑结果,这就是 HTML 规范。 不过滤用户输入是一种有风险的“最佳实践”。您正在为开发人员的错误打开大门,而在大型项目中,开发人员的错误发生,因此您会一次又一次地被黑客入侵。如果您决定走这条路,请记住这一点。 @LachoTomov 为了发现开发人员的错误,我建议使用默认转义的模板引擎。输入修改有两个显着的缺点:数据丢失和错误的安全感。例如,人们的名字中可以有撇号。您无法过滤掉所有可能在任何情况下都不好的东西,但是如果过滤掉了明显的东西,开发人员可能对转义不太警惕,并且冒烟测试可能会在不应该通过的时候通过。 @Kornel 肯定有办法抵御这种情况。但是您并不总是可以控制其他开发人员使用什么。例如。如果您正在构建一些公共 API。如果它返回不安全的数据,50% 以上的网站将被黑客入侵。是的,您可以将其归咎于其他开发人员,但这不是想法 - 网站仍然被黑客入侵 :) 所以正确的方法取决于特定的用例。【参考方案4】:

我最近通过chriso发现了node-validator。

示例

get('/', function (req, res) 

  //Sanitize user input
  req.sanitize('textarea').xss(); // No longer supported
  req.sanitize('foo').toBoolean();

);

XSS 函数弃用

此库中不再提供 XSS 功能。

https://github.com/chriso/validator.js#deprecations

【讨论】:

他们一个月前删除了 xss 支持。【参考方案5】:

您也可以查看ESAPI。有一个javascript version of the library。它非常坚固。

【讨论】:

【参考方案6】:

在较新版本的validator 模块中,您可以使用以下脚本来防止 XSS 攻击:

  var validator = require('validator');

  var escaped_string = validator.escape(someString);

【讨论】:

正如nealpoole.com/blog/2013/07/… 中指出的那样——您不能简单地使用转义过滤器来防止 XSS。 OWASP XSS 预防备忘单中解释了更多详细信息。您仍应使用 Google Caja Sanitizer。【参考方案7】:

试用 npm 模块 strip-js。它执行以下操作:

净化 HTML 删除脚本标签 删除“onclick”、“onerror”等包含 JavaScript 代码的属性 删除包含 JavaScript 代码的“href”属性

https://www.npmjs.com/package/strip-js

【讨论】:

不幸的是,我发现这个库删除了有效的 CSS 标记,例如 !important【参考方案8】:

您应该尝试库 npm "insane"。 https://github.com/bevacqua/insane

我在生产中尝试过,效果很好。大小非常小(压缩后约 3kb)。

清理 html 移除所有评估js的属性或标签 您可以允许您不想清理的属性或标签

文档非常易于阅读和理解。 https://github.com/bevacqua/insane

【讨论】:

【参考方案9】:

2021-04-16 更新:xss 是一个用于过滤用户输入以防止 XSS 攻击的模块。

使用白名单指定的配置清理不受信任的 HTML(以防止 XSS)。

访问https://www.npmjs.com/package/xss 项目主页:http://jsxss.com

【讨论】:

以上是关于在 Node.js / 服务器端 javascript 中防止 XSS的主要内容,如果未能解决你的问题,请参考以下文章

我们如何在服务器端使用 Node.js

如何在 Node.js 的服务器端使用 Object.values()

在Javascript(node.js,express.js,ejs)中访问服务器端变量[关闭]

黑客可以访问/复制/下载部署在Node Js上的JS服务器端代码吗?

node.js 的服务器端模板

在 node.js 中使用 fabric.js 渲染和操作服务器端画布