Production Best Practices: Security

Overview

术语"生产"指的是应用程序或API通常可供其最终用户或消费者使用的软件生命周期中的阶段. 相反,在"开发"阶段,您仍在积极地编写和测试代码,并且该应用程序不接受外部访问. 相应的系统环境分别称为生产开发环境.

开发和生产环境通常设置不同,并且有很大不同的要求. 开发中的优点在生产中可能是不可接受的. 例如,在开发环境中,您可能希望详细记录错误以进行调试,而相同的行为可能会在生产环境中成为安全问题. 在开发中,您不必担心可伸缩性,可靠性和性能,而这些问题在生产中变得至关重要.

注意 :如果您认为自己在Express中发现了安全漏洞,请参阅" 安全策略和过程" .

生产中Express应用程序的安全最佳实践包括:

Don’t use deprecated or vulnerable versions of Express

Express 2.x和3.x不再维护. 这些版本中的安全性和性能问题不会得到解决. 不要使用它们! 如果您尚未迁移到版本4,请按照迁移指南进行操作 .

另外,请确保您没有使用" 安全更新"页面上列出的任何易受攻击的Express版本. 如果是这样,请更新到稳定版本之一,最好是最新版本.

Use TLS

如果您的应用处理或传输敏感数据,请使用传输层安全性 (TLS)来保护连接和数据. 这项技术会在将数据从客户端发送到服务器之前对其进行加密,从而防止了一些常见(且容易)的黑客攻击. 尽管Ajax和POST请求在浏览器中可能不明显,但似乎"隐藏",但它们的网络流量容易受到数据包嗅探中间人攻击 .

您可能熟悉安全套接字层(SSL)加密. TLS只是SSL的下一步发展 . 换句话说,如果您以前使用过SSL,请考虑升级到TLS. 通常,我们建议Nginx处理TLS. 有关在Nginx(和其他服务器)上配置TLS的良好参考,请参阅推荐的服务器配置(Mozilla Wiki) .

另外,获得免费TLS证书的便捷工具是Let's Encrypt ,它是由Internet Security Research Group(ISRG)提供的免费,自动和开放的证书颁发机构(CA .

Use Helmet

头盔可以通过适当设置HTTP标头来帮助保护您的应用程序免受某些知名的网络漏洞的侵害.

头盔实际上只是一些较小的中间件功能的集合,这些功能设置了与安全性相关的HTTP响应标头:

像其他模块一样安装头盔:

$ npm install --save helmet

然后在您的代码中使用它:

// ...

var helmet = require('helmet')
app.use(helmet())

// ...

At a minimum, disable X-Powered-By header

如果您不想使用头盔,则至少禁用X-Powered-By标头. 攻击者可以使用此标头(默认情况下启用)来检测运行Express的应用程序,然后发起针对性的攻击.

因此,最佳实践是使用app.disable()方法关闭标头:

app.disable('x-powered-by')

如果您使用helmet.js ,它将为您解决这一问题.

Note: Disabling the X-Powered-By header does not prevent a sophisticated attacker from determining that an app is running Express. It may discourage a casual exploit, but there are other ways to determine an app is running Express.

Use cookies securely

为确保cookie不会打开您的应用程序以进行利用,请不要使用默认的会话cookie名称,并适当地设置cookie安全性选项.

有两个主要的中间件cookie会话模块:

这两个模块之间的主要区别在于它们如何保存cookie会话数据. 快速会话中间件将会话数据存储在服务器上; 它将会话ID仅保存在cookie本身中,而不保存会话数据. 默认情况下,它使用内存存储,并且不适用于生产环境. 在生产中,您需要设置一个可伸缩的会话存储; 请参阅兼容的会话存储列表.

相反, cookie会话中间件实现了cookie支持的存储:它将整个会话序列化为cookie,而不仅仅是会话密钥. 仅当会话数据相对较小且容易编码为原始值(而不是对象)时才使用它. 尽管浏览器每个cookie至少应支持4096字节,但为确保不超出限制,每个域的大小不得超过4093字节. 另外,请注意,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会话中间件的示例:

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
  }
}))

Prevent brute-force attacks against authorization

确保登录端点受到保护,以使私有数据更安全.

一种简单而强大的技术是使用两个指标来阻止授权尝试:

  1. 第一个是使用相同用户名和IP地址的连续失败尝试次数.
  2. 第二个是一段时间内来自IP地址的失败尝试次数. 例如,如果IP地址在一天之内进行100次失败尝试,则将其阻止.

rate-limiter-flexible软件包提供了使该技术轻松快速的工具. 您可以在文档中找到暴力保护的示例

Ensure your dependencies are secure

使用npm管理应用程序的依赖项功能强大且方便. 但是,您使用的软件包可能包含严重的安全漏洞,这些漏洞也可能影响您的应用程序. 您的应用程序的安全性仅与依赖项中的"最弱链接"一样强大.

从npm @ 6开始,npm会自动检查每个安装请求. 您也可以使用" npm audit"来分析您的依赖树.

$ npm audit

如果您想保持更安全,请考虑Snyk .

Snyk提供了命令行工具Github集成 ,可以根据Snyk的开源漏洞数据库检查您的应用程序中是否存在依赖项中的任何已知漏洞. 如下安装CLI:

$ npm install -g snyk
$ cd your-app

使用此命令来测试您的应用程序的漏洞:

$ snyk test

使用此命令打开一个向导,该向导将引导您完成应用更新或修补程序的过程,以修复发现的漏洞:

$ snyk wizard

Avoid other known vulnerabilities

注意可能会影响Express或应用程序使用的其他模块的Node Security ProjectSnyk咨询. 通常,这些数据库是有关节点安全性的知识和工具的绝佳资源.

最后,与其他任何Web应用程序一样,Express应用程序也容易受到各种基于Web的攻击. 熟悉已知的网络漏洞,并采取预防措施来避免它们.

Additional considerations

这是出色的Node.js安全清单中的一些进一步建议. 有关这些建议的所有详细信息,请参阅该博客文章:

by  ICOPY.SITE