如何保护Express.js APIs的安全 - Escape.tech

作者:API传播员 · 2025-12-12 · 阅读时间:6分钟

想要确保您的 Express.js 数据泄露、跨站脚本攻击(XSS)以及其他常见的安全问题。


什么是 Express.js?

Express.js 是一个基于 Node.js 的轻量级 Web 应用框架,以其快速、简洁和高度可扩展的特性而闻名。它为开发人员提供了强大的工具来处理路由、管理中间件以及与数据库交互,从而简化了服务器端应用程序的开发过程。

Express.js 的灵活性和直观设计使其成为构建 Web 和移动应用程序的理想选择。它在 Node.js 生态系统中得到了广泛应用,是开发人员开发高效、可扩展应用的首选框架。


为什么保护 Express.js 应用程序很重要?

保护 Express.js 应用程序的安全至关重要。由于 Express.js 广泛使用第三方模块,可能会引入潜在的安全漏洞。此外,Node.js 的异步特性可能导致开发者忽视安全问题,从而增加应用程序遭受攻击的风险。

如果没有适当的安全措施,Express.js 应用程序可能会面临以下威胁:

  • 注入攻击:如 SQL 注入和命令注入。
  • 跨站脚本攻击(XSS):恶意脚本可能被注入到用户浏览器中。
  • 数据泄露:敏感信息可能被未经授权的用户访问。

如何保护 Express.js API 的安全

1. Express.js 安全基础

在开发 Express.js 应用程序时,安全性应始终是优先考虑的事项。以下是一些基础安全措施:

  • 安全处理用户输入:防止 XSS 和 SQL 注入等漏洞。可以通过参数化查询或转义用户输入来实现。
  • 使用 Helmet 中间件:Helmet 提供了一组安全功能,如设置 HTTP 头,防止常见的安全威胁。

示例代码:

const express = require('express');
const helmet = require('helmet');
const app = express();

app.use(helmet());
  • 转义用户生成的内容:在模板引擎中使用 escape 函数,确保用户数据安全显示。
const escape = require('escape-html');

app.get('/page', (req, res) => {
  const userGeneratedContent = getUserGeneratedContent();
  const escapedContent = escape(userGeneratedContent);
  res.render('page', { content: escapedContent });
});

通过这些基础措施,您可以显著提高应用程序的安全性。


2. 防范常见安全威胁

跨站脚本攻击(XSS)

XSS 攻击可能导致敏感信息泄露或用户会话被劫持。以下是防范措施:

  • 验证和净化用户输入。
  • 使用 Helmet 的 xssFilter() 方法。
app.use(helmet.xssFilter());

跨站请求伪造(CSRF)

通过在表单中实现 CSRF 令牌,可以有效防止 CSRF 攻击。

SQL 注入

使用参数化查询或预处理语句来防止未经授权的 SQL 查询。

const query = "SELECT * FROM users WHERE id = ?";
db.query(query, [userId], (err, result) => {
  // 处理查询结果
});

3. 实施安全最佳实践

保持依赖项最新

定期更新依赖项以修复已知漏洞:

npm install -g npm-check-updates
ncu -u
npm install

实施身份验证和授权

使用强大的身份验证和授权机制,确保只有经过验证的用户才能访问应用程序。

示例:使用 bcrypt 加密用户密码。

const bcrypt = require('bcrypt');
const saltRounds = 10;

const hashedPassword = await bcrypt.hash(password, saltRounds);

验证和净化用户输入

通过使用 express-validator 等库,可以验证和净化用户输入,防止恶意数据进入系统。

const { body, validationResult } = require('express-validator');

app.post('/login', [
  body('username').isLength({ min: 5 }),
  body('password').isLength({ min: 8 })
], (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  // 继续处理登录逻辑
});

实现安全标头

设置安全标头以防止常见攻击。

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  res.setHeader('Strict-Transport-Security', 'max-age=31536000');
  next();
});

4. 进阶安全措施

基于角色的访问控制(RBAC)

通过定义用户角色,限制特定操作的访问权限。

const roles = ['user', 'admin'];

function checkRole(role) {
  return (req, res, next) => {
    const userRole = req.user.role;
    if (roles.indexOf(userRole) >= roles.indexOf(role)) {
      next();
    } else {
      res.status(403).send('权限被拒绝');
    }
  };
}app.get('/admin', checkRole('admin'), (req, res) => {
  res.send('Admin Dashboard');
});

多因素身份验证(MFA)

使用 speakeasyQRCode 库实现 MFA。

const speakeasy = require('speakeasy');
const QRCode = require('qrcode');

app.get('/setupMFA', (req, res) => {
  const secret = speakeasy.generateSecret({ length: 20 });
  QRCode.toDataURL(secret.otpauth_url, (err, data_url) => {
    res.json({ secret: secret.base32, QRCode: data_url });
  });
});

基于令牌的身份验证

使用 JSON Web Token(JWT)实现基于令牌的身份验证。

const jwt = require('jsonwebtoken');

const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '1d' });

实现速率限制

通过限制客户端请求频率,防止滥用和 DDoS 攻击。

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  message: '请求过多,请稍后再试'
});app.use(limiter);

总结

保护 Express.js API 的安全需要综合考虑多种安全措施。从基础的用户输入验证到进阶的多因素身份验证和速率限制,每一步都至关重要。通过实施这些最佳实践,您可以显著降低安全风险,保护您的应用程序和用户数据。

原文链接: https://escape.tech/blog/how-to-secure-express-js-api/