接受潜在危险的字符并阻止存储的XSS

时间:2016-10-12 20:11:28

标签: security xss

我在Web应用程序中有一些字段,其要求是接受任何字符并将它们存储在数据库中。它们后来被检索并显示了一些方法,包括JQuery绑定,MVVM框架等。

接受和处理这些数据的正确方法是什么?在存储数据之前是否对服务器端的数据进行编码或以原始格式存储?我是否要分析每种渲染方法以了解它们如何安全地处理数据?

1 个答案:

答案 0 :(得分:1)

TL; DR:这是后者,XSS是输出编码问题。

您可以在数据库中存储任何用户输入,这些用户输入本身不容易受到攻击。当然,如果可以,您应该进行输入验证,但有时由于您在正常操作中所期望的数据的性质,您无法真正验证某些输入。这不是一个大问题,无论如何,XSS通常无法通过输入验证来停止。

反对在数据库中存储编码值的一个论点是它是一个关注事物的分离。有几种不同的编码(HTML,Javascript,URL,XML等),接收数据的组件可能(并且应该)与稍后呈现它的那个无关。反对它的另一个论点与此相关,在存储数据时,您不想知道它将如何呈现,因此您无法选择正确的编码。对于编码数据,搜索或排序也将更加困难。所以你应该按原样存储它。

为了防止XSS,在将这些数据写入某种输出时,必须根据上下文(普通html,javascript,json,xml等)仔细实现输出编码。请注意,这根本不是直截了当的,例如在HTML页面中,不仅脚本块创建了javascript上下文,而且例如事件属性(onclick,onmouseover等)也会这样做,而< href的href也是如此。 a> tag,如果变量是href值的第一个字符(请参阅javascript:alert(1))。

但最重要的是,你总是需要找到正确的编码方法,并在将所有变量写入输出时对其进行编码。

MVVM是一种特殊情况。大多数客户端模板都有编写变量编码或原始的方法,客户端数据绑定通常提供将变量绑定为解析的html节点或文本的工具。显然,你应该选择文本,如果涉及用户输入,html可能容易受到XSS的攻击。这实际上意味着在Knockout中使用text:绑定而不是html:,或使用jQuery的.text()方法而不是.html()

在这些情况下,数据通常作为JSON下载到AJAX请求中,在那里它仍然不需要编码,因为你仍然不知道你将在哪里使用它,你可能仍然想要搜索/在客户端上排序(但为了使其不易受攻击,您需要使用application/json内容类型发送,而不是text/html)。但它只是数据,而JSON只是一种数据格式。当然,它需要编码为JSON,但标准对象序列化器会为您执行此操作。如果你想在页面中生成JSON(比如初始化SPA),你需要对JSON对象中的值进行HTML编码 - 用AJAX获取这些数据会更好更容易。