""" Express.js 框架安全知识 """ from ..base import KnowledgeDocument, KnowledgeCategory EXPRESS_SECURITY = KnowledgeDocument( id="framework_express", title="Express.js Security", category=KnowledgeCategory.FRAMEWORK, tags=["express", "nodejs", "javascript", "api"], content=""" Express.js 是Node.js最流行的Web框架,需要注意多种安全问题。 ## 常见漏洞模式 ### NoSQL注入 ```javascript // 危险 - MongoDB查询注入 app.post('/login', async (req, res) => { const user = await User.findOne({ username: req.body.username, password: req.body.password }); // 攻击: {"username": {"$ne": ""}, "password": {"$ne": ""}} }); // 安全 - 类型验证 app.post('/login', async (req, res) => { const { username, password } = req.body; if (typeof username !== 'string' || typeof password !== 'string') { return res.status(400).json({ error: 'Invalid input' }); } const user = await User.findOne({ username, password }); }); ``` ### 原型污染 ```javascript // 危险 - 合并用户输入 const merge = require('lodash.merge'); app.post('/config', (req, res) => { merge(config, req.body); // 攻击: {"__proto__": {"isAdmin": true}} }); // 安全 - 使用Object.assign或白名单 app.post('/config', (req, res) => { const allowed = ['theme', 'language']; allowed.forEach(key => { if (req.body[key]) config[key] = req.body[key]; }); }); ``` ### 命令注入 ```javascript // 危险 const { exec } = require('child_process'); app.get('/ping', (req, res) => { exec(`ping ${req.query.host}`, (err, stdout) => { res.send(stdout); }); }); // 安全 - 使用execFile和参数数组 const { execFile } = require('child_process'); app.get('/ping', (req, res) => { execFile('ping', ['-c', '4', req.query.host], (err, stdout) => { res.send(stdout); }); }); ``` ### XSS ```javascript // 危险 - 直接输出用户输入 app.get('/search', (req, res) => { res.send(`