项目中总结出来提高NodeJS程序安全性的最佳实践
作为开发人员,我们有责任提高应用程序的安全性以防止这些攻击。因此,在本文中,我将讨论您可以遵循的 6 个最佳实践,以提高 Node.js 应用程序的安全性。
1 验证用户输入
多年来,基于注入的攻击一次又一次进入 OWASP(开放 Web 应用程序安全项目)和 SANS Top 25 CWE(常见弱点枚举)。
因此,基于注入的攻击可以有多种形式;XSS、SQL 注入、主机头注入和操作系统命令注入是这些攻击的一些示例。
在这种情况下,我们需要在应用程序处理数据之前验证所有输入,以减轻基于注入的攻击。
例如,电话号码字段必须仅接受包含特定数字和特殊字符的可接受格式。
2 使用反向代理添加一层安全保护
允许通过反向代理访问 Web 应用程序提供了一个附加层,可以在请求到达 Web 应用程序之前过滤掉请求。但是,我们可以配置该层仅允许接受特定数量的请求,并确保服务器不会被请求淹没。
例如,我们可以使用开源 NGINX Web 服务器作为反向代理。以下示例展示了如何设置 NGINX 代理配置的速率限制。
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /login/ {
limit_req zone=mylimit;
proxy_pass http://my_upstream;
}
}
我们可以使用反向代理来实现连接超时。它确保网络服务器保持单个连接的活动时间不会超过所需的时间。
3 管理应用程序机密
在任何应用程序中,管理数据库连接字符串、API 密钥和凭据等敏感机密都是必需的。因此,我们应该不惜一切代价防止将这些秘密保留在代码库中,并遵循标准方法来存储它们。
例如,操作系统内的环境变量可以存储这些敏感信息,我们可以使用Node.js来调用这些环境变量。
然而,在某些情况下,应用程序需要实例化多个变量。这时候管理秘密的最好方法就是使用dotenv 包。
dotenv库每周 NPM 下载量超过 2200 万次,您可以使用 npm 或 Yarn 轻松安装它,如下所示**:**
# NPM
npm install dotenv
# Yarn
yarn add dotenv
然后,.env
在项目根目录创建一个文件并定义该文件中的所有机密。
host=awdoij3225kjbasd
USERNAME=topsecret
PASSWORD=definitelynotasecret
最后,您可以在应用程序中要求并使用这些机密,如下所示:
require('dotenv').config();
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
})
最重要的是,确保.env
在文件中包含文件.gitignore
,以防止它们被推送到 Git 存储库。
4 使用 HTTP 响应标头
HTTP 标头由不区分大小写的名称组成,后跟冒号 (:),然后是其值。
strict-transport-security:max-age=63072000
x-frame-options:DENY
Web 服务器使用 HTTP 响应标头来传达有关响应的附加信息。但它们与消息内容无关。这些 HTTP 标头指示浏览器遵循某些操作或以特定模式处理响应。
现在,让我们看看如何使用这些 HTTP 标头来提高应用程序的安全性。
HTTP Strict Transport Security
我们可以使用 HTTP 严格传输安全响应标头来确保浏览器仅使用安全的 HTTPS 连接与应用程序交互。此 HTTP 响应标头有助于防止 cookie 劫持和协议降级等攻击。
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options
X-Frame Options 标头通过指示浏览器显示框架内的内容来防止点击劫持攻击。此特定 HTTP 响应标头可使用以下选项:
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from: CUSTOM_DOMAIN
X-Content-Type-Options
X-Content-Type-Options 标头将阻止浏览器更改 Content-Type 标头中公布的 MIME 类型。此标头允许您通过说明 MIME 类型是有意配置的来避免 MIME 类型嗅探。
X-Content-Type-Options: nosniff
5 服务器端日志记录和监控
使用良好的日志记录库将为开发人员提供更强大的功能来排除故障和监视活动。另一方面,记录不需要的或太多的日志可能会影响应用程序的性能并占用更多资源。因此,我们在生产环境中部署应用程序时应该只使用合理的日志级别。
在构建日志消息时,必须对其进行格式化,以便人类和机器轻松阅读和理解日志。记录模糊的消息会导致开发人员之间产生误解。
以下示例显示了如何编写描述性日志消息。
Incorrect Description: Service Failed, Not Working
Correct Description: Application worker service failed due to insufficient disk space, ensure that adequate disk space is available and restart the Application worker service.
此外,确保日志记录机制捕获所有相关信息(包括 IP 地址、用户名、执行的操作等)也很重要。
不建议在应用程序日志中捕获或存储敏感信息。这违反了 PCI、GDPR 等主要应用程序合规性要求。但是,在某些情况下我们可能需要记录此类信息。在这种情况下,建议在收集敏感信息并将其写入日志之前对其进行屏蔽。
6 使用安全检查器捕获代码中的漏洞
代码检查器可以帮助开发人员在编译之前识别代码中的各种问题。他们可以检测最常见的问题并迫使开发人员遵循最佳实践。
这些代码检查器有自己的规则,开发人员可以根据需求进行自定义。因此,开发人员在使用之前必须从 linter 配置中启用与安全漏洞检测相关的规则。