保护生产中 Node.js 应用程序安全的 15 项最佳实践

在后端开发方面,Node.js 是开发人员最喜欢的技术之一。它的受欢迎程度不断上升,现已成为在线攻击的主要目标之一。这就是为什么保护 Node.js 免受漏洞和威胁至关重要。

在本指南中,您将看到为生产设计安全 Node.js 应用程序架构的 15 种最佳实践。实施所有这些实践,让您的后端比以往任何时候都更安全!


文章目录

    • 为什么应该构建安全的 Node.js 应用程序?
    • 让 Node.js 应用程序更安全的 15 个最佳实践
      • 1.切勿使用 Root 权限运行 Node.js
      • 2.让你的 NPM 库保持最新
      • 3.避免使用默认的 Cookie 名称
      • 4.设置安全 HTTP 标头
      • 5.实施速率限制
      • 6.确保强大的身份验证策略
      • 7.不要发送不必要的信息
      • 8.监控你的后端
      • 9.采用仅 HTTPS 的策略
      • 10.验证用户输入
      • 11.使用安全检查器
      • 12.防止 SQL 注入
      • 13.限制请求大小
      • 14.通过自动化工具检测漏洞
      • 15.让漏洞报告更简单
    • 结论


为什么应该构建安全的 Node.js 应用程序?

构建安全的 Node.js 应用程序非常重要,至少有以下三个原因:

  1. 保护用户数据:您的应用程序可能会处理敏感的用户信息,如个人信息、登录凭证、支付数据或机密的业务见解。如果不能保护这些数据,您可能会被隐私监管机构处以数百万美元的罚款。通过实施强大的安全措施,您可以保护用户数据并避免法律问题。
  2. 保护应用程序功能:安全漏洞可能会损害后端提供的功能。攻击者可能会利用弱点来改变您的服务、操纵数据或注入恶意代码。通过保护您的应用程序,您可以避免这种情况,并为您的用户提供无缝的体验。
  3. 维护声誉:安全事件可能会严重损害您的声誉并削弱对您服务的信任。客户和用户希望他们的数据得到安全处理,并且您的应用程序能够按预期运行。违规可能会导致失去信任,但通过优先考虑安全性,您可以表明您对质量的承诺。

您可能认为安全问题并没有那么普遍,遵循编码和架构最佳实践就足够了,但事实并非如此。 Node.js 的强大之处在于 NPM 环境,它提供了数百万个库。问题是大多数 NPM 包都存在一些安全漏洞。

换句话说,如果 Node.js 项目的依赖项不安全,那么它就不安全。考虑到使用外部库的流行程度,这是令人担忧的。根据 Snyk 开源安全状况报告,平均一个 Node.js 项目在 79 个直接依赖项中存在 49 个漏洞。这一相关统计数据强调了保护 Node.js 应用程序的重要性。

让 Node.js 应用程序更安全的 15 个最佳实践

1.切勿使用 Root 权限运行 Node.js

不建议使用 root 权限运行 Node.js,因为这违反了最小权限原则。无论您的后端是在专用服务器还是 Docker 容器上,您都应该始终以非 root 用户身份启动它。

如果您使用 root 权限运行 Node.js,则项目或其依赖项中的任何漏洞都可能被利用来获得对系统的未经授权的访问。例如,攻击者可以利用它们执行任意代码、访问敏感文件,甚至控制整个机器。因此,必须避免使用 Node.js 的 root 用户。

这里的最佳实践是创建一个专门的用户来运行 Node.js。该用户应仅具有启动应用程序所需的权限。这样,成功破坏您后端的攻击者将被限制为该用户的权限,从而限制了他们可能造成的潜在损害。

2.让你的 NPM 库保持最新

NPM 库使构建功能齐全的 Node.js 后端变得更容易、更快捷。同时,它们还会给您的应用程序带来安全风险。新的漏洞一直在被发现,维护人员的工作就是解决这些漏洞并发布软件包的更新版本。这就是为什么您应该保持依赖项最新的原因。

为了确保您所依赖的 NPM 库的安全,您可以使用 npm audit 和 snyk 。这些工具分析项目的依赖关系树并提供对任何已知漏洞的见解。

这是运行 npm audit 的示例:

npm audit
...
found 4 vulnerabilities (2 low, 2 moderate)
run `npm audit fix` to fix them, or `npm audit` for details

此命令利用 GitHub Advisory 数据库并检查您的 package.jsonpackage-lock.json 是否存在已知安全问题。

此外,您可以使用 Snyk 检查您对 Snyk 开源漏洞数据库的依赖关系。安装 snyk

npm install -g snyk

在项目的根文件夹中,使用以下命令测试您的应用程序:

snyk test

要打开一个向导来引导您完成修补所发现的漏洞的过程,请运行:

snyk wizard

使用 snyk 并定期运行 npm audit 可帮助您在 NPM 库中的安全问题成为问题之前识别并修复它们。请记住,应用程序的安全性取决于依赖项中最薄弱的环节。

3.避免使用默认的 Cookie 名称

Node.js 应用程序使用的 cookie 名称可能会无意中泄露您的后端所基于的技术堆栈。这是有价值的信息,您应该始终隐藏它,因为攻击者可以再次使用它。通过了解您正在使用的框架,他们可以利用与其相关的特定弱点。

详细而言,攻击者往往将注意力集中在会话 cookie 的名称上。通过使用 express-session 中间件设置自定义会话 cookie 名称来保护您的应用程序免受此类影响:

const express = require("express");
const session = require("express-session");

const app = express();
app.use(
  session({
    // set a custom name for the session cookie
    name: "myCustomCookieName",
    // a secure secret key for session encryption
    secret: "mySecretKey",
  })
);

4.设置安全 HTTP 标头

Express 中默认的 HTTP 标头不是很安全。我们使用在线 Security Headers 项目检查标头安全性:

其中一些标头包含不应公开的信息,如 X-Powered-By。还有一些则是缺失的,应该添加进来,以处理各种与安全相关的问题,包括防止跨站脚本 (XSS) 攻击。

这就是 helmet 发挥作用的地方!该库负责根据安全标头的建议设置最重要的安全标头。使用方法如下:

const express = require("express");
const helmet = require("helmet");

const app = express();
// register the helmet middleware
// to set the security headers
app.use(helmet());

helmet() 中间件会自动删除不安全的标头并添加新的标头,包括 X-XSS-ProtectionX-Content-Type-OptionsStrict-Transport-SecurityX-Frame-Options。这些都是最佳实践,有助于保护您的应用程序免受常见攻击。

Node.js 应用程序设置的标头现在将被视为安全:

5.实施速率限制

DDoS(分布式拒绝服务)和暴力破解是两种最常见的 Web 攻击。为了缓解它们,您可以实施速率限制。此技术涉及控制 Node.js 后端的传入流量,防止恶意行为者用过多的请求淹没您的服务器。

实施速率限制的最简单方法是通过 rate-limiter-flexible 库。该依赖库提供了一个可配置的中间件,用于限制在指定时间内来自同一 IP 地址或用户的请求数量。

以下是如何使用它在 Node.js 中应用速率限制的示例:

const express = require("express");
const {
  RateLimiterMemory,
} = require("rate-limiter-flexible");

const app = express();
const rateLimiter = new RateLimiterMemory({
  points: 10, // 允许的最大请求数
  duration: 1, // 时间范围,以秒为单位
});
const rateLimiterMiddleware = (req, res, next) => {
  rateLimiter
    .consume(req.ip)
    .then(() => {
      // 请求被允许,继续处理请求
      next();
    })
    .catch(() => {
      //超过请求限制,使用适当的错误消息进行响应
      res.status(429).send("Too Many Requests");
    });
};
app.use(rateLimiterMiddleware);

首先,初始化一个速率限制器实例,允许 1 秒内最多 10 个请求。然后,在自定义中间件中使用它来分析传入请求的 IP。如果未超出速率限制,则请求将继续。否则,请求将被阻止并且服务器返回 429 Too Many Requests 响应。

6.确保强大的身份验证策略

为了保护您的 Node.js 应用程序免受利用用户身份验证的攻击,您需要实施强身份验证策略。首先,邀请用户设置强密码。此外,您还应该支持多重身份验证 (MFA) 和单点登录 (SSO)。 MFA 通过要求用户提供多种形式的身份验证来增加额外的安全层,而 SSO 则简化了身份验证过程并降低了弱密码或重复使用密码的风险。

当需要对密码进行散列存储时,应首选 bcrypt 等强大的加密函数,而不是 Node.js crypto 库提供的方法。该软件包提供了一种安全的密码散列算法,大大增加了攻击者破解密码的难度。最后,如前所述,通过限制登录失败次数来减少暴力破解攻击。

7.不要发送不必要的信息

无意中提供给攻击者的任何信息都可能被用来对付你。因此,服务器响应只应包含调用者严格需要的内容。例如,避免直接向客户端返回详细的错误信息或堆栈跟踪。取而代之的是,提供不透露具体实现细节的通用错误信息。最简单的方法是在生产模式下运行 Node.js,设置 NODE_ENV=production env,否则 Express 会在错误响应中添加堆栈跟踪。

同样,您必须小心 API 响应中包含的数据。仅返回必要的数据字段,并避免暴露调用者未请求的敏感信息。这将最大限度地减少意外泄露机密或特权信息的风险。

8.监控你的后端

您在生产中的后端可能正在遭受攻击,而您可能根本没有意识到这一点。这就是监控 Node.js 应用程序至关重要的原因。通过将其连接到应用程序性能监控 (APM) 工具,您可以对其进行跟踪,以发现安全问题并确保其整体健康。

幸运的是,有几个可用于 Node.js 的 APM 库和服务。其中最受欢迎的一些是 SigNoz、Sentry、Prometheus、New Relic 和 Elastic,它们提供了应用程序各个方面的信息,包括性能、错误率、资源使用情况和安全相关指标。特别是,它们可以实现实时数据收集和检测可能表明安全漏洞的异常或可疑活动。其中一些还提供可维护性功能,以跟踪 CI/CD 管道中的部署工作流程。

9.采用仅 HTTPS 的策略

通过确保只能通过 HTTPS 访问后端,您将提高客户端和 Node.js 服务器之间交换数据的机密性。 HTTPS 建立一个加密通道,保护密码、会话令牌和用户数据等敏感信息免遭拦截。

作为此类政策的一部分,您还应该使用 HTTPS cookie。为此,请确保 Node.js 应用程序设置的任何 cookie 都标记为 securehttpOnly

res.cookie("myCookie", "cookieValue", {
  // create an HTTPS cookie
  secure: true,
  httpOnly: true,
});

意外方或脚本将无法再访问您的 cookie。此外,它们只能通过 HTTPS 连接传输。

10.验证用户输入

每当用户有机会输入内容时,攻击者就可以利用它向服务器发送恶意数据。因此,验证用户输入对于确保 Node.js 应用程序的安全性和完整性至关重要。

11.使用安全检查器

安全检查器会分析您的代码库,以识别漏洞、不安全的代码部分和最佳实践违规行为。其中最流行的是 eslint-plugin-security ,这是一组用于在 Node.js 中实施安全开发的 ESLint 规则。

通过将此类工具集成到您的开发工作流程中,您可以及早发现并解决安全问题。具体来说,它们可以降低编码时将漏洞引入应用程序的风险。这些工具在集成到 CI/CD 管道中时特别有效。

12.防止 SQL 注入

SQL 注入是一种常见的安全漏洞,当攻击者可以操纵传递到 SQL 查询的输入数据时就会发生这种漏洞。当将用户输入直接连接到 SQL 查询中时,通常会发生这种情况。在这种情况下,攻击者可以伪造旨在执行任意 SQL 代码的特定输入,从而导致未经授权的访问和数据泄露。

有多种方法可以防止 Node.js 中的 SQL 注入。最流行的是:

  • 使用准备好的语句或参数化查询:这些技术涉及将 SQL 代码与用户输入分离,防止其被解释为查询的一部分。
  • 输入清理:验证用户输入以拒绝恶意数据,降低 SQL 注入攻击的风险。
  • 使用 ORM:像 Sequelize 这样的 ORM 技术通常提供针对 SQL 注入的内置保护。

13.限制请求大小

Node.js 中的默认请求正文大小限制为 5 MB。为了保护您的后端免受恶意用户试图用数据淹没您的服务器的 DDoS 攻击,建议减少该限制。为此,您可以使用 body-parser 库并按如下方式配置它:

const express = require("express");
const bodyParser = require("body-parser");

const app = express();
// 将请求大小限制设置为1 MB
app.use(bodyParser.json({ limit: "1mb" }));

请根据您的具体要求调整该值。现在,正文大于 1 MB 的请求将立即被阻止,服务器将无法分配资源来处理这些请求。

14.通过自动化工具检测漏洞

自动漏洞扫描工具(例如 SonarQube 或类似工具)是识别 Node.js 应用程序中安全问题的宝贵资源。这些工具对代码库、依赖项、配置和其他组件执行全面扫描,以识别安全漏洞。

以下是使用自动漏洞扫描器的一些主要好处:

  • 早期检测:在部署应用程序之前主动识别安全问题。
  • 增加覆盖范围:对所有项目文件进行深度扫描,确保高安全覆盖范围。
  • 持续监控:将它们集成到 CI/CD 管道中,以确保及时发现通过代码更改引入的任何新漏洞。

15.让漏洞报告更简单

让用户和安全研究人员能够报告 Node.js 后端中发现的漏洞是确保应用程序安全的另一个重要方面。这不仅应该是可能的,而且程序必须清晰且易于理解。

security.txt 提议的标准是让研究人员与您联系的有效方法。这是一个放置在项目根目录下的简单文本文件,提供有关如何报告安全漏洞的信息。它遵循标准化格式,包括联系方式、加密方法和披露指南。

以下是基本 security.txt 文件的示例:

Contact: email@example.com
Encryption: https://example.com/pgp-key.asc

Contact 指定应向其报告安全漏洞或问题的电子邮件地址。这些电子邮件可能包含关键信息,不应公开访问。因此, Encryption 字段指示组织的 PGP 公钥的位置,该公钥可用于加密电子邮件内的消息。这种机制确保只有组织才能使用私钥解密这些消息并读取它们。

同样,您也可以考虑在网站上添加“报告漏洞”页面。

结论

在本指南中,我们讨论了在生产中保护 Node.js 应用程序安全的方法。作为开发人员,我们有责任保护用户数据、维护应用程序功能并保护我们的声誉。

通过集成这些技术、方法和技巧,您可以创建更可靠的 Node.js 架构,降低风险并确保应用程序的安全性。


原文:https://semaphoreci.medium.com/best-practices-for-securing-node-js-applications-in-production-d24b7c4981d

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/111774.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打造美团外卖新体验,HarmonyOS SDK持续赋能开发者共赢鸿蒙生态

从今年8月起,所有升级到HarmonyOS 4的手机用户在美团外卖下单后,可通过屏幕上的一个“小窗口”,随时追踪到“出餐、取餐、送达”等订单状态。这个能让用户实时获悉订单进度的神奇“小窗口”,就是实况窗功能。 实况窗:简…

Intel oneAPI笔记--oneAPI简介、SYCL编程简介

oneAPI简介 Intel oneAPI是Intel提供的统一编程模型和软件开发框架。 它旨在简化可充分利用英特尔各种硬件架构(包括 CPU、GPU 和 FPGA)的应用程序的开发 oneAPI一个重要的特性是开放性,支持多种类型的架构和不同的硬件供应商,是…

QML 创建 Web 混合应用

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 随着互联网的快速发展,Web 应用在各个领域中变得越来越流行。为了满足用户对多样化功能的需求,我们经常需要将 Web 技术和原生应用相结合,来创建混合应用程序。 混合应用程序:是一种应用程序开发方法,它…

Microsoft 365 管理自动化

Microsoft 365 服务被大多数组织广泛使用,每天生成的数据量巨大。解决 Microsoft 365 中的问题可能非常困难,并且使用多个管理中心来保护组织变得复杂。本机控制台还缺少某些批量管理任务、全面的审计报告和基于角色的精细访问控制。 Microsoft 360 管理…

42 深度学习(六):调参|保存模型以及再次调用或训练

文章目录 卷积神经网络调参optimizer 优化器SGDmomentumAdaGradRMSPropadam学习率自适应经验之谈 激活函数SigmoidTanhReLULeaky-ReLU指数线性单元(ELU)Maxout(基本不用)经验之谈 初始化全部为 0判断初始化好不好批归一化(BN) 数据…

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…

一文带你速通Sentinel限流规则(流控)解读

目录 前置知识速补 基本介绍 流控模式 直接模式 关联模式 链路模式 流控效果 直接失败 Warm Up(预热) 排队等待 前置知识速补 QPS每秒查询率(Query Per Second):每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多…

Python项目——识别指定物品

目录 1、百度EasyDL平台数据配置 1.1、训练图像上传 1.2、训练图像进行标注 1.3、训练模型 1.4、检验识别 1.5、申请发布 1.6、控制台权限配置 2、Python调用物体识别API 本项目是基于百度EasyDL平台制作的识别转盘内瓶子,且识别瓶子位置的一个项目。通过在…

【备忘录】SpringBoot+ dynamic-datasource配置自定义多数据源

一、 业务场景解释 由于公司业务需要开发设计一款文件读取导入工具,导入的配置和目标数据库并不一定在同一个数据库地址,故需要使用到自定义数据源,并且支持数据源切换 大致场景如下: 二、工具选择 鉴于市面上有很多工具&#…

大数据之LibrA数据库系统告警处理(ALM-12005 OKerberos资源异常)

告警解释 告警模块对Manager中的Kerberos资源的状态进行监控,当Kerberos资源异常时,系统产生此告警。 当Kerberos资源恢复时,且告警处理完成时,告警恢复。 告警属性 告警参数 对系统的影响 Manager中的Kerberos资源异常&#…

CV论文阅读大合集

YearNameAreamodeldescriptiondrawback2021 ICMLClip (Contrastive Language-Image Pre-training)contrastive learning、zero-shot learing、mutimodel用文本作为监督信号来训练可迁移的视觉模型CLIP’s zero-shot performance, although comparable to…

车载以太网解决方案

近年来,为了满足智能网联汽车的开发要求,车载以太网技术开始逐渐进入人们的视野。而以太网技术已经成为下一代车载网络架构的趋势之一,其发展之迅猛,使得各主机厂纷纷产生了浓厚的兴趣并投入研发。 一 为什么使用车载以太网 | 对…

JDK环境变量配置

windows系统 1. win建 r 输入sysdm.cpl打开系统属性界面。选择高级栏目,点击环境变量菜单。 2. 选择系统变量中的新建,变量名输入JAVA_HOME,变量值输入jdk安装目录,例如:D:\Java\jdk1.8.0_91。 3. 选择编辑系统变量中…

企业通过ISO/IEC 27001的必要性阐述

文章目录 什么是ISO 27001?ISO 27001认证的必要性1,保护信息资产2,合规性要求3,提高客户信任4,降低安全风险5,提高内部效率6,改进供应链安全7,提高员工意识8,连续改进 推荐阅读 什么…

智能问答进阶之路:RAG(大模型检索增强生成)框架详解与实战,融合检索与生成助力智能系统更上层楼

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…

MyBatis-Plus返回getOne返回null疑惑

getOne返回null 问题描述分析过程总结 问题描述 在数据库建了一张表主要包括两个字段master_id和slave_id;主要的额外字段max_lots 默认值是null;当调用getOne进行查询是,返回是null 分析过程 总结

【深度学习】pytorch——快速入门

笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ pytorch快速入门 简介张量(Tensor)操作创建张量向量拷贝张量维度张量加法函数名后面带下划线 _ 的函数索引和切片Tensor和Numpy的数组之间的转换张量(tensor)与标量…

【MATLAB】全网唯一的13种信号分解+FFT傅里叶频谱变换联合算法全家桶

有意向获取代码,请转文末观看代码获取方式~ 大家吃一顿火锅的价格便可以拥有13种信号分解FFT傅里叶频谱变换联合算法,绝对不亏,知识付费是现今时代的趋势,而且都是我精心制作的教程,有问题可随时反馈~也可单独获取某一…

机器学习(六)构建机器学习模型

1.9构建机器学习模型 我们使用机器学习预测模型的工作流程讲解机器学习系统整套处理过程。 整个过程包括了数据预处理、模型学习、模型验证及模型预测。其中数据预处理包含了对数据的基本处理,包括特征抽取及缩放、特征选择、特征降维和特征抽样;我们将…

【Redis】认识Redis-特点特性应用场景对比MySQL重要文件及作用

文章目录 认识redisredis的主要特点redis的特性(优点)redis是单线程模型,为什么效率这么高,访问速度这么快redis应用场景redis不可以做什么MySQL和Redis对比启动RedisRedis客户端Redis重要文件及作用 认识redis redis里面相关的小…