将用户输入编码以存储在MongoDB中
我正在寻找在MongoDB中存储和显示用户输入的最佳实践。显然,在SQL数据库中,所有用户输入都需要进行编码,以防止注入攻击。不过,我了解到在MongoDB中,我们更需要担心的是XSS攻击。那么,用户输入在存储到MongoDB之前,是否需要在服务器上进行编码呢?还是说,只要在客户端使用像handlebars这样的模板库在显示之前进行编码就可以了?
我说的流程是这样的:
- 在客户端,用户将他们的名字更新为"<script>alert('hi');</script>"。
- 在发送到服务器之前,这个内容需要被转义成"<script>alert('hi');</script>"吗?
- 更新后的字符串通过ajax请求以JSON文档的形式传递给服务器。
- 服务器将这个字符串存储在MongoDB的"user.name"字段下。
- 为了安全起见,服务器是否也需要以同样的方式转义这个字符串?在完全转义之前,是否需要先解转义,以免出现'&'的重复?
- 稍后,客户端请求用户信息,名字字符串在JSON的ajax响应中发送。
- 在显示之前,用户的名字会使用类似_.escape(name)的方式进行编码。
这样的流程能正确显示信息并防止XSS攻击吗?对于像中文这样的Unicode字符又该如何处理呢?
这也可能会影响文本搜索的方式,因为如果所有用户文本都被编码,搜索词在开始搜索之前可能需要先进行编码。
非常感谢!
2 个回答
简单来说,是的,你应该对所有用户输入进行编码。
每当你把字符串拼接在一起时,需要正确地处理数据。MongoDB支持将JavaScript查询转换为它自己的查询语言表达式,使用的是BSON格式。在这个过程中,有两个需要注意的地方:
- 在JavaScript字符串内部
- 其他地方
如果你在字符串外部拼接用户输入,你真的需要小心。除非变量的数据类型是整数或类似的类型,这样可能的值是已知且有限的,否则很难正确处理转义。
最好的做法是尽量避免字符串拼接。你可以在这里了解更多关于MongoDB如何处理SQL注入的问题。
在把这段内容发送到服务器之前,是否需要把它转义成
"<script>alert('hi');</script>"
这样的形式?
不需要,只有在这段内容要放到HTML页面里时,才需要这样转义 - 就像上面提到的第(5)步。
在把文本放到新的环境中时,必须使用正确的转义方式。这意味着在你把数据放进HTML页面时,才需要进行HTML编码。理想情况下,你应该使用一个现代的模板系统,这样它会自动为你处理转义。
(同样,如果你在 <script>
块中包含数据作为JavaScript字符串,你就需要进行JavaScript编码;如果你在样式表规则中包含数据,就需要进行CSS编码,依此类推。如果我们使用SQL查询并在字符串中注入数据,那么就需要进行SQL转义,但幸运的是,Mongo查询通常是用JavaScript对象来完成的,而不是用字符串语言,所以不需要担心转义的问题。)
数据库不是HTML环境,所以在数据进入数据库时进行HTML编码并不是正确的做法。
(除了注入之外,还有其他来源可能导致XSS,最常见的是不安全的URL方案。)