装修素材图片都从什么网站找,自己做抽奖网站违法,wordpress需要会php,360搜索指数引言 在Web开发中#xff0c;安全性是一个不可忽视的话题。Node.js作为一个流行的后端平台#xff0c;同样需要关注各种潜在的安全威胁#xff0c;并采取措施加以防御。本文将介绍如何在Node.js应用中防御常见的Web攻击#xff0c;以及如何使用安全相关的中间件来加固安全性…引言 在Web开发中安全性是一个不可忽视的话题。Node.js作为一个流行的后端平台同样需要关注各种潜在的安全威胁并采取措施加以防御。本文将介绍如何在Node.js应用中防御常见的Web攻击以及如何使用安全相关的中间件来加固安全性。 防御常见的Web攻击
防御XSS攻击
跨站脚本攻击XSS是一种常见的攻击方式攻击者通过在页面插入恶意脚本来盗取用户信息或者进行其他恶意操作。为了防御XSS攻击我们需要对用户输入的内容进行转义处理。
const express require(express);
const app express();
//const bodyParser require(body-parser); // 引入body-parser模块用于解析请求体
//从Express 4.16.0版本开始
//body-parser模块的功能已经被集成到了Express本身中因此你可以不用单独安装body-parser而是直接使用express.json()和express.urlencoded()中间件
app.use(express.json()); // 用于解析JSON格式的请求体
app.use(express.urlencoded({ extended: true })); // 用于解析URL编码的请求体
app.post(/submit-comment, (req, res) {// 获取用户输入的评论内容let comment req.body.comment;// 对评论内容进行HTML转义防止XSS攻击comment escapeHtml(comment);console.log(提交的内容comment)// 存储评论内容到数据库等操作...// ...res.send(评论已提交);
});// HTML转义函数
function escapeHtml(text) {const map {: amp;,: lt;,: gt;,: quot;,: #039;};return text.replace(/[]/g, (m) map[m]);
}app.listen(3000, () {console.log(Server is running on port 3000);
});运行
防御CSRF攻击
跨站请求伪造CSRF攻击是一种利用用户已登录的身份在用户不知情的情况下进行恶意请求的攻击方式。为了防御CSRF攻击我们可以使用CSRF令牌。
const express require(express);
const csrf require(csurf);
const cookieParser require(cookie-parser);
const app express();
app.use(express.json()); // 用于解析JSON格式的请求体
app.use(express.urlencoded({ extended: true })); // 用于解析URL编码的请求体
// 使用cookie-parser中间件来解析cookie
app.use(cookieParser());
// 设置CSRF保护
const csrfProtection csrf({ cookie: true });app.get(/form, csrfProtection, (req, res) {// 发送带有CSRF令牌的表单到客户端res.send(form action/submit-form methodPOSTinput typehidden name_csrf value${req.csrfToken()}input typetext namedatabutton typesubmit提交/button/form);
});app.post(/submit-form, csrfProtection, (req, res) {// 处理表单提交res.send(表单数据已提交);
});app.listen(3000, () {console.log(Server is running on port 3000);
});运行 http://localhost:3000/form http://localhost:3000/submit-form
防御注入攻击
注入攻击尤其是SQL注入是攻击者通过输入恶意数据篡改后端数据库查询的一种攻击方式。为了防御注入攻击我们应该使用参数化查询。
MongoDB
const express require(express);
const mongoose require(mongoose);
const app express();
app.use(express.json()); // 用于解析JSON格式的请求体
app.use(express.urlencoded({ extended: true }));// 连接MongoDB数据库 注释掉用于运行测试用例
// mongoose.connect(mongodb://localhost:27017/userDB);// 创建用户模型
const User mongoose.model(User, new mongoose.Schema({username: String,password: String
}));app.post(/login, async (req, res) {// 获取用户输入的用户名和密码const { username, password } req.body;try {// 使用Mongoose的查询方法它会自动处理参数化查询防止NoSQL注入const user await User.findOne({ username, password }).exec();if (user) {res.send(登录成功);} else {res.send(用户名或密码错误);}} catch (error) {res.status(500).send(服务器错误);}
});// app.listen(3000, () {
// console.log(Server is running on port 3000);
// });module.exports app;mysql
const express require(express);
const mysql require(mysql);
const app express();app.use(express.urlencoded({ extended: true }));// 创建数据库连接
const connection mysql.createConnection({host: localhost,user: your_username,password: your_password,database: your_database
});app.post(/login, (req, res) {// 获取用户输入的用户名和密码const username req.body.username;const password req.body.password;// 使用参数化查询防止SQL注入const query SELECT * FROM users WHERE username ? AND password ?;connection.query(query, [username, password], (error, results) {if (error) throw error;if (results.length 0) {res.send(登录成功);} else {res.send(用户名或密码错误);}});
});app.listen(3000, () {console.log(Server is running on port 3000);
});使用安全相关的中间件
使用Helmet加固HTTP头部
Helmet是一个集成了多个安全相关的HTTP头部设置的中间件它可以帮助你设置一些安全相关的HTTP头部来增强应用的安全性。
const express require(express);
const helmet require(helmet);
const app express();// 使用Helmet中间件
app.use(helmet());// 其他路由和中间件...
// ...app.listen(3000, () {console.log(Server is running on port 3000);
});使用rate-limiter-flexible限制请求频率
为了防止恶意用户或者机器人进行暴力破解或者DDoS攻击我们可以使用rate-limiter-flexible来限制请求的频率。
const express require(express);
const { RateLimiterMemory } require(rate-limiter-flexible);
const app express();
const port 3000;// 配置内存中的限速器
const rateLimiter new RateLimiterMemory({points: 5, // 允许每个IP在一定时间内累积的最大点数duration: 1, // 一个时间窗口的长度秒// 还有其他可配置的选项
});// 限速器中间件
const rateLimiterMiddleware (req, res, next) {rateLimiter.consume(req.ip).then(() {next(); // 在未超出限制的情况下继续处理请求}).catch(() {res.status(429).send(Too Many Requests); // 当达到限制时发送429状态});
};app.use(rateLimiterMiddleware);app.get(/limit-query, (req, res) {res.send(Hello World!);
});app.listen(port, () {console.log(App listening at http://localhost:${port});
});测试 为了自动化测试和模拟连续的请求您可以在Linux或Mac终端中使用以下简单的bash循环命令
for i in {1..10}; do curl http://localhost:3000/limit-query; done运行结果
测试用例
防御XSS攻击的测试用例
//test18.js 修改部分代码
app.post(/submit-comment, (req, res) {// ...res.send(comment);
});
// test18.test.js
const request require(supertest);
const app require(../test18); // 你的Express应用导出在test18.js文件中describe(XSS Attack Prevention,(){it(它应该转义HTML字符以防止XSS,async (){const maliciousString scriptalert(xss)/script;const response await request(app).post(/submit-comment).send({comment: maliciousString})expect(response.text).not.toContain(maliciousString);expect(response.text).toContain(lt;scriptgt;alert(quot;xssquot;)lt;/scriptgt;);})
})测试结果
防御CSRF攻击的测试用例
// test18-2.test.js
const request require(supertest);
const app require(../test18-2); describe(CSRF Attack Prevention, () {test(它应该提供CSRF令牌, async () {const getResponse await request(app).get(/form);console.log(1111111,getResponse.text)expect(getResponse.text).toMatch(/name_csrf/);});test(它应该拒绝没有CSRF令牌的表单提交, async () {const postResponse await request(app).post(/submit-form).send({ data: test });expect(postResponse.statusCode).toBe(403);});
});测试结果
防御注入攻击的测试用例
// 引入mongoose用于操作MongoDB数据库
const mongoose require(mongoose);
// 引入mongodb-memory-server用于创建MongoDB内存服务器便于进行测试
const { MongoMemoryServer } require(mongodb-memory-server); //版本6.9.6
// 引入supertest用于模拟HTTP请求
const supertest require(supertest);
// 引入你的app用于测试
const app require(../test18-4);// 定义一个变量用于存储MongoDB内存服务器的实例let mongoServer;// 在所有测试用例执行前启动MongoDB内存服务器并连接
beforeAll(async () {mongoServer new MongoMemoryServer();const mongoUri await mongoServer.getUri();mongoose.connect(mongoUri);
});
// 在所有测试用例执行完毕后断开数据库连接并停止MongoDB内存服务器
afterAll(async () {mongoose.disconnect();await mongoServer.stop();
});describe(NoSQL Injection Prevention, (){it(它不应该允许NoSQL注入,async () {// 创建用户模型const User mongoose.model(User2, new mongoose.Schema({username: String,password: String}));const user new User({ username: user1, password: password1 });await user.save(); // 保存用户到数据库// 尝试使用注入攻击的方式查询用户const maliciousUsername user1 {$ne: null}; // 这是一个注入攻击的尝试const maliciousPassword password1 {$ne: null}; // 这是一个注入攻击的尝试const response await supertest(app).post(/login).send({ username: maliciousUsername, password: maliciousPassword });expect(response.body.message).not.toBe(登录成功);})
})测试结果
总结
通过上述的措施我们可以显著提高Node.js应用的安全性从而更好地保护用户数据和服务的稳定性。当然这些只是安全性加固的一部分实际应用中还需要根据具体情况采取更多的安全措施。