毫无疑问,Node.js如今是愈来愈成熟。尽管这样,咱们尚未造成不少的安全准则。
在这篇文章中,我会分享一些关于提升Node.js安全性方面的技巧。php
你不只仅要避免使用eval - 你也应该避免使用在下列状况,他们等价于直接使用eval;node
setInterval(String, 2) setTimeout(String, 2) new Function(String)
注* eval: 直接将字符串转化为代码执行,如: eval('alert("hi")')nginx
若是你对用户输入的内容进行了eval运行(千万不要这么设计),你就有可能受到注入攻击。而且这种运行方式很慢。shell
使用这种模式将限制你的变量声明,并总会将一些可能隐藏的错误抛出来,下面是几个例子:安全
'use strict'; delete Object.prototype; // TypeError
'use strict'; var obj = { a: 1, a: 2 }; // syntax error
var obj = { x: 17 }; with (obj) // !!! syntax error { }
使用 JSLint, JSHint 或 ESLint 来静态分析你的代码. 静态代码分析可让你在早期捕获一些潜在的BUG.服务器
这一点不言而喻:测试,测试再测试。cookie
不只仅是单元测试,你应该进行全面测试(test pyramid)。app
不少人使用超级用户权限运行Node应用,不是吗?由于他们但愿应用程序直接侦听80或443端口(注* http和https的默认端口)dom
这一点是不对的,进程中的任何一个错误/漏洞都将让整个系统宕机,而后你就什么也干不了。单元测试
因此你应该使用一个HTTP反向代理服务去转发这些请求。能够用nginx, Apache 你看着办。
下面的代码段有什么问题?
child_process.exec('ls', function (err, data) { console.log(data); });
child_process.exec 命令调用的是 /bin/sh, 它启动了一个解释器,而非程序。
这是有问题的,当该方法执行用户输入的一个方法,比于一个反引号或$()中的内容,一个新的命令就可能被攻击者注入。
为了不这个问题,你只须要使用child_process.execFile。详解。
建立文件时,如处理上传的文件格外注意。这些文件能够轻松吃掉你全部的磁盘空间。
为了解决这个问题,你应该使用Streams。
不光是Node-全部的Web应用程序都应该加密。(注* https)
发生这种状况时,攻击者注入可执行代码的HTTP响应。一个应用程序容易受到这种类型的攻击,它会在客户端执行未验证的脚本(主要是用Javascript写的)。它使攻击者可以窃取cookie,剪贴板的内容或修改页面自己。
好比
http://example.com/index.php?user=<script>alert(123)</script>
若是这条用户查询未通过验证直接插入到DOM(HTML)中,它就会被执行。
永远不要往DOM中插入不可信的数据
在插入前去除HTML
默认状况下,Cookie能够经过Javascript在同一个域中读取。这样可能会被跨站点脚本攻击。并且它们还有可能被第三方的JavaScript库阅读。
例如
var cookies = document.cookie.split('; ');
为了防止这种状况,你能够在Cookies上使用HttpOnly,这个标签可让JavaScript没法读取这个cookie。 (注* 好比服务器端用到的Cookie)
内容安全策略(CSP)是一个附加的安全层,帮助检测和缓解某些类型的攻击,包括跨站点脚本(XSS)和数据注入攻击。
CSP能够经过 Content-Security-Policy 被启用。
好比:
Content-Security-Policy: default-src 'self' *.mydomain.com
注* CSP的更多内容
这个header头信息将只接收信任的域名及其子域名的发过来的内容。
CSRF是一种迫使终端用户在他目前已验证受权的Web应用程序中执行其它的actions。
这时侯问题就可能发生了,由于cookie也会发送到被请求的网站(此网站你已经被受权) - 即便当这些请求来自不一样的位置。
例如
<body onload="document.forms[0].submit()"> <form method="POST" action="http://yoursite.com/user/delete"> <input type="hidden" name="id" value="123555."> </form> </body>
注* 此页面在另一个域名中
这样会直接致使这个用户信息被删除。
为了防止CSRF,您应该实现同步令牌模式 - 幸运的是,node社区已经帮你作了。下面是它的工做原理:
当发起一个GET请求时,服务器检查你的CSRF令牌 - 若是它不存在,建立一个
当用户显示输入时,确保添加一个隐藏的CSRF令牌值
当Form表单提交时,确保该值与该表单与Session中的内容相匹配