Ubuntu环境下JavaScript(Node.js)安全防护关键措施
以root权限运行Node.js会放大安全漏洞的危害(如攻击者获取root访问权)。应在Ubuntu上创建专用用户(如nodeuser),并赋予其运行应用的最小权限(仅能访问应用目录和必要资源)。例如:
sudo adduser nodeuser # 创建专用用户
sudo chown -R nodeuser:nodeuser /path/to/app # 将应用目录所有权转移给该用户
su - nodeuser -c "node app.js" # 以专用用户启动应用
此做法可限制攻击者在应用被攻破后的权限范围。
第三方依赖(如npm包)是安全漏洞的主要来源。需通过以下方式管理依赖:
nvm安装Node.js:避免系统包管理器(apt)的固定版本,便于更新到最新稳定版(含安全补丁)。例如:curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
source ~/.bashrc
nvm install --lts # 安装最新的LTS版本
npm audit检查项目依赖的已知漏洞,npm outdated查看过时依赖,及时更新或替换有漏洞的包;也可使用Snyk等第三方工具进行深度扫描。用户输入是恶意攻击的常见入口,需严格验证和清理:
DOMPurify(前端)或express-validator(后端)过滤用户输入,移除恶意脚本标签。例如:const expressValidator = require('express-validator');
app.post('/submit', [
expressValidator.body('comment').trim().escape() // 转义HTML特殊字符
], (req, res) => {
// 处理验证通过的输入
});
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('db', 'user', 'password', { dialect: 'mysql' });
const User = sequelize.define('User', { name: DataTypes.STRING });
// 参数化查询(防止SQL注入)
User.findAll({ where: { name: req.query.name } });
通过安全配置减少攻击面:
X-XSS-Protection、X-Content-Type-Options、Strict-Transport-Security),防范XSS、点击劫持等攻击。例如:const helmet = require('helmet');
app.use(helmet()); // 启用所有安全头部
secure(仅通过HTTPS传输)和httpOnly(禁止JavaScript访问)。例如:const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/cert.pem')
};
https.createServer(options, app).listen(443);
app.use((req, res, next) => {
if (!req.secure) res.redirect(`https://${req.headers.host}${req.url}`); // 重定向HTTP到HTTPS
else next();
});
res.cookie('sessionId', '12345', { secure: true, httpOnly: true }); // 安全cookie
https://trusted-domain.com),避免恶意网站访问你的API。使用rate-limiter-flexible等库限制同一IP或用户的请求频率,缓解DDoS攻击和暴力破解(如密码猜测)。例如:
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: 10, // 1分钟内最多10次请求
duration: 60 // 时间窗口(秒)
});
app.use((req, res, next) => {
rateLimiter.consume(req.ip)
.then(() => next()) // 允许请求
.catch(() => res.status(429).send('Too Many Requests')); // 超过限制返回429
});
可针对登录接口、API端点单独设置更严格的速率限制。
通过日志记录和监控工具识别异常行为:
winston或bunyan记录请求日志(如IP、URL、状态码),避免记录敏感信息(如密码、银行卡号)。例如:const winston = require('winston');
const logger = winston.createLogger({
transports: [new winston.transports.File({ filename: 'app.log' })],
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
)
});
app.use((req, res, next) => {
logger.info(`${req.method} ${req.url} - ${req.ip}`); // 记录请求信息
next();
});
NODE_ENV=production,禁用Express的堆栈跟踪(避免泄露代码细节);使用环境变量(如.env文件)存储敏感信息(如数据库密码、API密钥),而非硬编码在代码中。ufw(Ubuntu防火墙)限制入站流量,仅允许必要的端口(如80、443、22)。例如:sudo ufw allow 22/tcp # 允许SSH
sudo ufw allow 80/tcp # 允许HTTP
sudo ufw allow 443/tcp # 允许HTTPS
sudo ufw enable # 启用防火墙
rsync或cron定期备份应用数据和数据库,防止数据丢失或被篡改。