4.生产最佳实践:安全性 | 4. Production Best Practices: Security
生产最佳实践:安全
概观
术语“生产”
指的是软件生命周期中的一个阶段,即应用程序或API通常可供其最终用户或消费者使用。相反,在“开发”
阶段,您仍然在积极编写和测试代码,并且该应用程序不对外部访问开放。相应的系统环境分别被称为生产
和开发
环境。
开发和生产环境通常以不同的方式建立,并具有完全不同的要求。生产中可能无法接受发展中的问题。例如,在开发环境中,您可能需要详细记录错误以进行调试,而同样的行为可能会成为生产环境中的安全问题。在开发过程中,您无需担心可扩展性,可靠性和性能,而这些担忧在生产中变得至关重要。
注意
:如果您认为您发现了Express中的安全漏洞,请参阅安全策略和过程。
生产中的Express应用程序的安全最佳实践包括:
- 请勿使用Express的已弃用或易受攻击的版本
- 使用TLS
- 使用头盔
- 使用cookies安全
- 确保您的依赖性是安全的
- 避免其他已知的漏洞
- 额外的考虑
请勿使用Express的已弃用或易受攻击的版本
Express 2.x和3.x不再维护。这些版本中的安全和性能问题不会被修复。不要使用它们!如果您尚未移至版本4,请按照迁移指南进行操作。
同时确保您未使用安全更新页面上列出的任何易受攻击的Express版本。如果是,请更新到其中一个稳定版本,最好是最新版本。
使用TLS
如果您的应用处理或传输敏感数据,请使用传输层安全性(TLS)来保护连接和数据。该技术在将数据从客户端发送到服务器之前对其进行加密,从而防止一些常见(并且容易)的黑客攻击。虽然Ajax和POST请求可能不明显,并且在浏览器中似乎“隐藏”,但它们的网络流量很容易受到数据包嗅探和中间人攻击。
您可能熟悉安全套接字层(SSL)加密。TLS只是SSL的下一个进程(https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v = vs.85%29.aspx)。换句话说,如果您使用的是以前的SSL,可以考虑升级到TLS,一般来说,我们推荐Nginx来处理TLS,关于在Nginx(和其他服务器)上配置TLS的很好的参考,请参阅推荐的服务器配置(Mozilla Wiki)。
此外,获得免费TLS证书的便捷工具还包括由互联网安全研究组(ISRG)提供的免费,自动化和开放的认证机构(CA)Let's Encrypt。
使用头盔
通过适当设置HTTP标头,头盔可以帮助保护您的应用免受一些着名的网络漏洞攻击。
头盔实际上只是九个较小的中间件功能的集合,它们设置了与安全相关的HTTP头文件:
- csp设置
Content-Security-Policy
标题以帮助防止跨站脚本攻击和其他跨站点注入。
- hidePoweredBy删除
X-Powered-By
标题。
- hsts设置
Strict-Transport-Security
标头,强制执行到服务器的安全(HTTP over SSL / TLS)连接。
- ieNoOpen设置
X-Download-Options
为IE8 +。
- noCache设置
Cache-Control
和Pragma标题来禁用客户端缓存。
- noSniff设置
X-Content-Type-Options
为防止浏览器从MIME中嗅探到已声明的内容类型的响应。
- frameguard设置
X-Frame-Options
标题以提供点击劫持保护。
- xssFilter设置
X-XSS-Protection
为在最新的Web浏览器中启用跨站点脚本(XSS)过滤器。
像其他模块一样安装头盔:
$ npm install --save helmet
然后在代码中使用它:
// ...
var helmet = require('helmet')
app.use(helmet())
// ...
至少,禁用X-Powered-By标头
如果你不想使用头盔,那么至少要禁用X-Powered-By
头部。攻击者可以使用此标头(默认情况下启用)检测运行Express的应用程序,然后启动专门针对性的攻击。
所以,最好的做法是用app.disable()
方法关闭标题:
app.disable('x-powered-by')
如果你使用helmet.js
它,它为你照顾这个。
注意
:禁用X-Powered-By header
并不能防止复杂的攻击者确定应用程序正在运行Express。它可能会阻止偶然的利用,但还有其他方式可以确定应用程序正在运行Express。
使用cookies安全
为确保cookie不会将您的应用打开,请不要使用默认会话cookie名称并适当设置cookie安全选项。
有两个主要的中间件cookie会话模块:
- 快速会话,取代
express.session
Express 3.x内置的中间件。
- cookie会话,用于替换
express.cookieSession
Express 3.x中内置的中间件。
这两个模块的主要区别是它们如何保存cookie会话数据。该快递会话服务器上的中间件存储会话数据; 它只会将会话ID保存在cookie本身中,而不是会话数据。默认情况下,它使用内存中的存储,而不是为生产环境设计的。在制作中,您需要设置一个可扩展的会话存储; 请参阅兼容会话存储的列表。
相反,Cookie会话中间件实现了cookie支持的存储:它将整个会话序列化为cookie,而不仅仅是会话密钥。仅当会话数据相对较小并且易于编码为原始值(而不是对象)时才使用它。虽然浏览器应支持每个cookie至少4096个字节,但为确保不超过限制,请不要超过每个域4093个字节的大小。此外,请注意,客户端可以看到Cookie数据,因此如果有任何理由保证其安全或模糊,那么Express-session可能是更好的选择。
不要使用默认的会话cookie名称
使用默认会话cookie名称可以打开您的应用程序以进行攻击。构成的安全问题类似于X-Powered-By
:潜在的攻击者可以使用它来指纹服务器并相应地针对攻击。
为了避免这个问题,使用通用的cookie名称; 例如使用快速会话中间件:
var session = require('express-session')
app.set('trust proxy', 1) // trust first proxy
app.use(session{
secret: 's3Cur3',
name: 'sessionId'
}))
设置Cookie安全选项
设置以下cookie选项以增强安全性:
secure
- 确保浏览器仅通过HTTPS发送Cookie。
httpOnly
- 确保cookie仅通过HTTP(S)而不是客户端JavaScript发送,有助于防止跨站脚本攻击。
domain
- 表示cookie的域名; 使用它来与请求URL的服务器的域进行比较。如果它们匹配,则检查下一个路径属性。
path
- 表示Cookie的路径; 用它来比较请求路径。如果这个和域名匹配,然后发送请求中的cookie。
expires
- 用于设置持久性cookie的到期日期。
以下是使用Cookie会话中间件的示例:
var session = require('cookie-session')
var express = require('express')
var app = express()
var expiryDate = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
app.use(session{
name: 'session',
keys: ['key1', 'key2'],
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate
}
}))
确保您的依赖性是安全的
使用npm来管理你的应用程序的依赖是强大和方便的。但是,您使用的软件包可能包含严重的安全漏洞,这些漏洞也可能会影响您的应用程序。您的应用程序的安全性与您的依赖关系中的“最薄弱的环节”一样强大。
使用以下两种工具中的一种或两种来帮助确保您使用的第三方软件包的安全性:nsp和Snyk。
nsp是一个命令行工具,用于检查Node Security项目漏洞数据库,以确定您的应用程序是否使用具有已知漏洞的软件包。安装如下:
$ npm i nsp -g
使用此命令提交npm-shrinkwrap.json
/ package.json
文件进行验证,以nodesecurity.io:
$ nsp check
Snyk提供了一个命令行工具和一个Github集成,可以检查您的应用程序与Snyk的开源漏洞数据库是否存在相关性中的任何已知漏洞。按如下所示安装CLI:
$ npm install -g snyk
$ cd your-app
使用此命令测试您的应用程序是否存在漏洞:
$ snyk test
使用此命令打开一个向导,引导您完成应用更新或修补程序以修复找到的漏洞的过程:
$ snyk wizard
避免其他已知的漏洞
留意Node Security Project或Snyk建议,这些建议可能会影响Express或您的应用使用的其他模块。一般来说,这些数据库是关于节点安全性的知识和工具的绝佳资源。
最后,Express应用程序 - 就像任何其他网络应用程序 - 可能容易受到各种基于Web的攻击。熟悉已知的网络漏洞并采取预防措施以避免它们。
额外的考虑
以下是一些优秀的Node.js安全检查表的进一步建议。有关这些建议的所有详细信息,请参阅该博客文章:
- 实施限速以防止对认证的暴力攻击。一种方法是使用StrongLoop API网关来执行限速策略。或者,您可以使用中间件(如express-limiter),但这样做会需要您稍微修改代码。
- 使用csurf中间件来防止跨站请求伪造(CSRF)。
- 始终过滤和清理用户输入以防止跨站点脚本(XSS)和命令注入攻击。
- 通过使用参数化查询或预准备语句来防御SQL注入攻击。
- 使用开源sqlmap工具来检测应用程序中的SQL注入漏洞。
- 使用safe-regex来确保您的正则表达式不受正则表达式拒绝服务攻击的影响。