JavaScript 应用程序安全:十大漏洞
JavaScript,尤其是在 Node.js 环境中,已成为现代 Web 开发的基石。然而,它的流行也使应用程序成为有吸引力的攻击目标。忽视安全问题可能导致数据泄露、财务损失和声誉损害。在本文中,我们将基于 OWASP Top 10 标准,分析 JavaScript (Node.js) 应用程序最关键的十大漏洞,并通过代码示例展示如何防范它们。
1. 注入 (Injection)
注入仍然是最危险的威胁之一。在 Node.js 环境中,最常见的是 SQL 注入和 NoSQL 注入(例如,在 MongoDB 中)。
问题
直接将用户输入拼接到数据库查询中,允许攻击者执行任意代码。
有漏洞的代码示例
const user = req.body.username;const query = `SELECT * FROM users WHERE username = '${user}'`;db.query(query, callback);解决方案
使用参数化查询或 ORM/ODM。对于 MongoDB,请使用 mongo-sanitize。
const query = 'SELECT * FROM users WHERE username = $1';db.query(query, [user], callback);2. 身份验证和会话管理失效
弱身份验证是账户被盗的直接途径。
问题
使用可预测的令牌(例如,使用 none 算法的 JWT)、以明文形式存储密码或缺乏登录尝试次数限制。
漏洞示例
// 未验证算法的 JWTconst token = jwt.sign({ user: 'admin' }, 'secret', { algorithm: 'none' });解决方案
- 始终验证 JWT 算法:
jwt.verify(token, secret, { algorithms: ['HS256'] })。 - 通过
bcrypt或argon2存储密码。 - 实施登录尝试限制 (
express-rate-limit)。
const bcrypt = require('bcrypt');const saltRounds = 10;const hash = await bcrypt.hash(password, saltRounds);3. XSS (跨站脚本攻击)
XSS 允许将恶意脚本注入到网页中,然后在受害者的浏览器中执行。
问题
未经过滤地输出用户内容,尤其是在 Next.js 或 Nuxt.js 中使用服务端渲染 (SSR) 时。
有漏洞的代码 (Express)
res.send(`<h1>Hello, ${req.query.name}</h1>`);解决方案
- 转义输出:使用
escape-html库或具有自动转义功能的模板引擎 (EJS, Pug)。 - 设置 CSP (内容安全策略) 标头:
helmet.contentSecurityPolicy()。
const helmet = require('helmet');app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"] }}));4. 不安全的直接对象引用 (IDOR)
当用户可以通过知道或猜测对象的标识符来访问对象(文件、数据库记录)时,就会出现此漏洞。
示例
app.get('/api/user/:id', (req, res) => { // 没有检查 req.user.id === req.params.id const user = db.findUser(req.params.id); res.json(user);});解决方案
始终在服务器端检查访问权限。
if (req.user.id !== req.params.id) { return res.status(403).send('Forbidden');}5. 不安全的配置
这包括使用默认凭据、在生产环境中启用调试模式以及错误的 CORS 设置。
问题
// 开放的 CORSapp.use(cors({ origin: '*' }));