保护 Express 免受 XSS 攻击:对整个传入请求的 HTML 个实体进行编码是否足够?
Protect Express against XSS: is it sufficient to encode HTML entities of whole incoming request?
我有一个 Express 应用程序,我想防止 XSS。
我红了一些关于 XSS 的页面 - 包括 OWASP 个页面,鉴于我的应用程序特性,我决定编写一个编码 HTML 个实体的中间件 - 更准确地说 XML实体,包括 <>"'
- 我在路由中使用它们之前的请求参数。
我还在连接时刷新会话 cookie,以防止 cookie 被盗。
我如何构建我的应用程序
- 所有AJAX个请求都是POST(所有参数都被中间件改写)
- 我不使用 GET 参数
- 我使用的路由参数应该是 int,如果不是,我会报错。
- 唯一不是来自用户输入的数据来自 OAuth 个人数据检索,当它们进入我的应用程序时我也会对其进行清理
- 在页面加载时执行的客户端 JS 仅涉及来自数据库的数据,假设它们在进入数据库时已被中间件清理。
- window.location安全使用
- 我还没有使用任何外部客户端 JS 库(如 JQuery 或 FileUpload)——也许我稍后会在代码中添加它们
- 当用户输入一些东西时,它总是被发送到服务器(通过 AJAX POST),我借此机会发回经过净化的输入以在 JS and/or DOM 而不是初始输入
- 我不使用 eval
我的感受
我得出的结论是,通过这种行为(在外部数据到来时对其进行清理)我避免了所有存储和反射的 XSS,并且 windows.location 的正确使用阻止了基于 DOM 的 XSS。
这个结论对吗,还是我忘记了什么?我还应该使用一些 helmet 功能吗?
编辑
我的问题不是什么是最好的 HTML 服务器端消毒剂(即使它是其中的一部分),我更想知道我在代码中放置的保护是否在全球范围内保护我的应用程序免受所有攻击众所周知的 XSS 类型。特别是我想知道我的中间件是否是一个坏习惯。
实际上 XSS filtering function in PHP 至少没有涵盖基于 DOM 的 XSS 攻击(因为它只涵盖服务器端 HTML 清理)。
我列出了我的应用程序的一些特殊性,以便对我忘记的任何一点或会使应用程序暴露于 XSS 漏洞的不良架构模式提供反馈。
编辑 2
我选择 Erlend 的答案是最好的,但是 msoliman 的答案也很出色,并且是对 Erlend 答案的补充。
虽然你在这里做得很好,但我认为你应该考虑这一点:转义数据以避免 XSS 需要依赖于上下文。 OWASP XSS 预防作弊 sheet 对此进行了详细解释。
恕我直言,从客户端接收数据时,您应该根据域确保数据有效。这就是您使用路由参数所做的。您希望它是一个 int,如果不是,则拒绝。对于其他数据类型,您应该做同样的事情。这是一个有效的名字吗? (名字通常不包含 < 或 >)。这是有效的邮政编码吗?这将阻止很多攻击,因为攻击通常包含在给定上下文中无效的字符。
说到阻止攻击,XSS、SQL 注入等都是同一个问题的子类。在将数据添加到 HTML(或 XML 或 SQL 查询等)时,您必须对数据进行转义,并且需要针对给定的上下文进行转义。如何转义数据取决于它是否在标签之间,作为属性值,在 CSS 等
内
通过尝试在进入的过程中对事物进行清理,您最终可能会发现您的清理功能不够好,并且您有 partially/wrongfully 个经过清理的数据,这将是一个搞砸了。
总结:
a)
途中根据域验证和拒绝
b) 在输出期间执行基于上下文的转义
您可以在客户端清理 html .. Sanitize/Rewrite HTML on the Client Side
您也可以按照以下线程检查如何在服务器端进行操作以获得更好的安全性
Preventing XSS in Node.js / server side javascript
我有一个 Express 应用程序,我想防止 XSS。
我红了一些关于 XSS 的页面 - 包括 OWASP 个页面,鉴于我的应用程序特性,我决定编写一个编码 HTML 个实体的中间件 - 更准确地说 XML实体,包括 <>"'
- 我在路由中使用它们之前的请求参数。
我还在连接时刷新会话 cookie,以防止 cookie 被盗。
我如何构建我的应用程序
- 所有AJAX个请求都是POST(所有参数都被中间件改写)
- 我不使用 GET 参数
- 我使用的路由参数应该是 int,如果不是,我会报错。
- 唯一不是来自用户输入的数据来自 OAuth 个人数据检索,当它们进入我的应用程序时我也会对其进行清理
- 在页面加载时执行的客户端 JS 仅涉及来自数据库的数据,假设它们在进入数据库时已被中间件清理。
- window.location安全使用
- 我还没有使用任何外部客户端 JS 库(如 JQuery 或 FileUpload)——也许我稍后会在代码中添加它们
- 当用户输入一些东西时,它总是被发送到服务器(通过 AJAX POST),我借此机会发回经过净化的输入以在 JS and/or DOM 而不是初始输入
- 我不使用 eval
我的感受
我得出的结论是,通过这种行为(在外部数据到来时对其进行清理)我避免了所有存储和反射的 XSS,并且 windows.location 的正确使用阻止了基于 DOM 的 XSS。
这个结论对吗,还是我忘记了什么?我还应该使用一些 helmet 功能吗?
编辑
我的问题不是什么是最好的 HTML 服务器端消毒剂(即使它是其中的一部分),我更想知道我在代码中放置的保护是否在全球范围内保护我的应用程序免受所有攻击众所周知的 XSS 类型。特别是我想知道我的中间件是否是一个坏习惯。
实际上 XSS filtering function in PHP 至少没有涵盖基于 DOM 的 XSS 攻击(因为它只涵盖服务器端 HTML 清理)。
我列出了我的应用程序的一些特殊性,以便对我忘记的任何一点或会使应用程序暴露于 XSS 漏洞的不良架构模式提供反馈。
编辑 2
我选择 Erlend 的答案是最好的,但是 msoliman 的答案也很出色,并且是对 Erlend 答案的补充。
虽然你在这里做得很好,但我认为你应该考虑这一点:转义数据以避免 XSS 需要依赖于上下文。 OWASP XSS 预防作弊 sheet 对此进行了详细解释。
恕我直言,从客户端接收数据时,您应该根据域确保数据有效。这就是您使用路由参数所做的。您希望它是一个 int,如果不是,则拒绝。对于其他数据类型,您应该做同样的事情。这是一个有效的名字吗? (名字通常不包含 < 或 >)。这是有效的邮政编码吗?这将阻止很多攻击,因为攻击通常包含在给定上下文中无效的字符。
说到阻止攻击,XSS、SQL 注入等都是同一个问题的子类。在将数据添加到 HTML(或 XML 或 SQL 查询等)时,您必须对数据进行转义,并且需要针对给定的上下文进行转义。如何转义数据取决于它是否在标签之间,作为属性值,在 CSS 等
内通过尝试在进入的过程中对事物进行清理,您最终可能会发现您的清理功能不够好,并且您有 partially/wrongfully 个经过清理的数据,这将是一个搞砸了。
总结:
a)
途中根据域验证和拒绝b) 在输出期间执行基于上下文的转义
您可以在客户端清理 html .. Sanitize/Rewrite HTML on the Client Side
您也可以按照以下线程检查如何在服务器端进行操作以获得更好的安全性
Preventing XSS in Node.js / server side javascript