Node.js变得越来越成熟,毋庸置疑——尽管如此,仍然没有多少关于安全方面的知识。
在这篇文章中我会分享一些就Node.js安全方面的东西。
摒弃eval,或者友好相处 eval不是唯一一个你在服务端情况下要避免使用在以下每种表达式中的:
-
setInterval(String, 2)
-
setTimeout(String, 2)
-
new Function(String)
但是为什么你需要避免eval呢?
它会暴露你的代码从而被注入攻击(用户输入的eval-哇哦,连写下来都困难,请别这么干)同时这也是效率低下的(因为它会让解释器来执行)。
请使用严格模式!
通过这个标识你可以使用受限制的javascript变量。这样排除了一些未知错误。
不可删除的属性
‘use strict’;
delete Object.prototype; // 类型错误
对象名必须唯一
‘use strict’;
var obj = {
a: 1,
a: 2
};
// syntax error 语法错误
不要使用 with 关键字
var obj = { x: 17 };
with (obj) // !!! syntax error 语法错误
{
}
想查看这些位置错误的完整列表,参照MDN
代码分析
可以借助JSLint, JSHint 或者 ESLint这几个工具。静态的代码分析可以在早期找出你代码中很多潜在的问题。
测试
更加不必说的,测试!测试!再多一点测试!
好吧,这不仅仅只是单元测试,你最好做一些循序渐进的测试。
向 sudo node app.js 说不!
我经常看到这个:人们总是用超级用户权限去运行他们的node应用。为什么?
因为他们想让他们的应用监听80端口和443端口。
这样是错误的!万一你的进程中发生一个错误或者bug可能会导致你整个系统崩溃,因为他被授权可以做任何事。
取而代之,你应该使用一个HTTP 服务器或者HTTP代理在传递请求。这可能是nginx、apache或者凡是你能说出的。
避免command注入
下面的这段代码有什么问题呢?
child_process.exec(‘ls’, function (err, data) {
console.log(data);
});
首先,在最前面的 child_process.exec 产生了一个对 /bin/sh 的调用。它是个bash 解释器而不是个程序加载器。
这在传递用户输入到这个方法的时候是有问题的因为他可以使一个重音符或者$(),攻击者可以注入一条新的命令。
要搞定这个问题只要使用child_process.execFile 就可以了。
原始的博文处理了命令行注入,参阅LiftSecurity。
临时文件
在创建文件时要格外注意,比如上传文件。这些文件很容易就耗尽你的硬盘空间。
要搞定这种问题的话,你的解决办法就是用流(Streams)。
加固你的web应用
这个部分不仅仅是针对Node,包括在一般情况你怎么使你的web应用更安全。
跨站脚本攻击
当攻击者通过HTTP响应注入了一段可执行的代码。当一个应用很容易受这种类型的攻击时,它会回传一段非法输入到客户端(通常以javascript形式编写)。它使得攻击者可以偷取cookie,到剪贴板并自行修改页面。
举例
http://example.com/index.php?user=<script>alert(123)</script>
如果查询串在不通过校验的情况下回传到客户端,并添加到DOM中,它就会执行。
怎样预防呢?
- 永远不要添加不可信的数据到DOM中
- 在添加之前先编码
更多信息跨站脚本攻击和怎样避免。
阻止cookie窃取
在默认情况下,cookie是可以被相同域的javascript读取的。这样的话,在发生跨站脚本攻击时就非常危险了。但是还不止这点:一个三方的javascript类库也可以读取它们。
举例
var cookies = document.cookie.split(’; ');
怎么防止这种情况呢?
你可以看看cookie中的HttpOnly标识,可以让javascript不能读取它。
** 内容安全政策**
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. CSP可以通过Content-Security-Policy 这个HTTP 头信息来生效。
Content-Security-Policy: default-src 'self' *.mydomain.com
这个会允许可信的域以及它的子域的内容。
伪造跨站请求
CSRF is an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. 这会发生是因为每个到一个网站的请求都附带着cookie,甚至包括那些其他网站的请求也是。
举例
上面的片段很容易导致结果是你的用户信息被删除。
怎样避免它呢?
为了防止跨站请求伪装,你需要实现同步的token,幸运的是在Node.js已经为你实现了。下面是他怎么工作的:
- 当一个GET请求开始接受服务端的CSRF检测的,如果不存在,则创建一个。
- 当一个显示用户输入的时候,保证添加一个含有CSRF token值的隐藏输入。
- 当表单提交的时候,保证数据是表单提交的,而且session是匹配的。
哪里翻译的不对或者有问题,欢迎指出。英文不溜求不拍砖。
作者:Gergely Nemeth 翻译:luoyjx 译文地址:Node.js安全的提醒 英文原文: Node.js Security Tips