Node.js 开发者发布到生产环境的安全漏洞

去年我为一家初创公司进行代码审查。代码看起来很整洁,测试也全部通过了。

然后我看到了这一行: const query = \SELECT * FROM users WHERE email = '${req.body.email}'``

这是一个 SQL 注入漏洞。这家初创公司在生产环境中运行了它 8 个月,没有任何开发人员或 CTO 发现它。

这些漏洞是隐形的,因为代码可以正常运行。在用户向输入框输入恶意命令之前,它看起来一切正常。

停止这 5 种常见的错误:

  1. 包含用户输入的原始 SQL 不要使用模板字符串进行查询。这会让攻击者能够访问你的数据库。
  • 错误:const query = \SELECT * FROM users WHERE email = '${email}'``
  • 正确:使用参数化查询。 const query = 'SELECT * FROM users WHERE email = $1' db.query(query, [email])
  1. 在 Git 中泄露密钥 开发人员经常将 .env 文件提交到代码库中。这会暴露你的数据库 URL 和 API 密钥。请务必将 .env 添加到你的 .gitignore 文件中。

  2. 使用 jwt.decode 而不是 jwt.verify jwt.decode 仅读取 Token。它不会检查 Token 是否真实有效。任何人都可以伪造一个已解码的 Token。

  • 错误:const user = jwt.decode(token)
  • 正确:务必验证签名。 const user = jwt.verify(token, process.env.JWT_SECRET)
  1. 身份验证接口缺少速率限制 如果没有速率限制,攻击者可以通过暴力破解尝试数百万个密码。请使用库来限制登录尝试次数。
  • 正确:设置每 15 分钟最多尝试 10 次的限制。
  1. 过于详细的错误信息 向客户端发送原始错误信息会帮助攻击者摸清你的系统架构。他们可以看到你的表名和数据库类型。
  • 错误:res.status(500).json({ error: error.message })
  • 正确:在内部记录错误,并向用户发送通用的提示信息。 res.status(500).json({ error: 'Something went wrong' })

在发布接口之前,请问自己一个问题: 如果用户发送了意料之外的数据,会发生什么?

安全漏洞很少是复杂的。它们往往发生在你忘记考虑恶意攻击者的时候。

你在生产环境中发现过什么样的安全漏洞?

来源:https://dev.to/manolito99/the-security-bug-every-nodejs-developer-ships-to-production-49e6