当前位置:网站首页>05. 博客项目之安全
05. 博客项目之安全
2022-07-06 05:17:00 【John是橘红】
博客项目之安全
SQL 注入:窃取数据库内容
XSS 攻击:窃取前端的 cookie 内容
密码加密:保障用户信息安全
补充
- server 端的攻击方式非常多,以防手段也非常多
- 本文章之讲常见的、能通过 web server (nodejs) 层面预防的
- 有些攻击需要硬件和服务来支持(需要 OP 支持),如 DDOS
1. SQL 注入
- 最原始、最简单的攻击,从有了 web2.0 就有了 SQL 注入攻击
- 攻击方式:输入一个 SQL 片段,最终拼接成一段攻击代码
- 预防措施:使用 MySQL 的 escape 函数处理输入内容即可
比如现在的登录验证,是通过字符串拼接后执行 SQL 语句来实现的:
const {
exec } = require("../db/mysql");
const login = (username, password) => {
const sql = ` select username, realname from users where username = '${
username}' and password = '${
password}'; `;
return exec(sql).then((rows) => {
return rows[0] || {
};
});
};
module.exports = {
login,
};
SQL 语句例如:
select username, realname from users where username = 'zhangsan' and password = '123456';
免密码用户
但是如果输入的用户名是 zhangsan ' --
,便将后边的语句注释了,就算密码错误也可以用 zhangsan 的账号登录。
select username, realname from users where username = 'zhangsan' -- ' and password = '123456';
删库
如果现在有人的用户名是 zhangsan';delect from users; --
,后果更严重,直接数据库全删了。
select username, realname from users where username = 'zhangsan';delect from users; -- ' and password = '123456';
解决方法
使用转义字符。将敏感的符号转义可以避免这个问题。mysql 库提供了 mysql.escape 方法,用来转义内容:
// controller/user.js
const {
exec, escape } = require("../db/mysql");
const login = (username, password) => {
username = escape(username);
password = escape(password);
const sql = ` select username, realname from users where username = ${
username} and password = ${
password}; `;
console.log(sql);
return exec(sql).then((rows) => {
return rows[0] || {
};
});
};
module.exports = {
login,
};
转义后的 SQL 语句如下:
select username, realname from users where username = 'zhangsan \' --' and password = '123';
username 整体被单引号包起来了,里面的单引号会被转义,因此不会影响到查询。
2. XSS 攻击
前端最熟悉的攻击方式,但 server 端更应该掌握
攻击方式:在页面展示内容中掺杂 js 代码,以获取网页信息
预防措施:转换生成 js 的特殊字符
2.1 XSS 攻击演示
我在发表博客的时候输入以下内容:
创建成功后跳转到管理中心,因为 HTML 里直接嵌入了 script 脚本,因此会执行 alert(document.cookie)
。因此转移会生成 script 脚本的符号是个有效的办法。
2.2 预防 XSS 攻击
安装第三方库:
yarn add xss
用法和上面的 escape 转义十分类似,只要将需要转义的字符串包起来即可。
// controller/blog.js
const newBlog = (blogData = {
}) => {
// blogData 是一个博客对象,包含 title、content、author 属性
blogData = {
...blogData,
createTime: Date.now(),
id: 3, // 表示新建博客,插入到数据表里面的 id
};
const {
title, content, author, createTime } = blogData;
const sql = ` insert into blogs (title, content, createTime, author) values ('${
xss(title)}', '${
xss(content)}', ${
createTime}, '${
author}');`;
return exec(sql).then((insertData) => {
// promise 返回插入的值对应的 id
return {
id: insertData.insertId,
};
});
};
实现效果:
转义后的 SQL 语句如下:
insert into blogs (title, content, createTime, author)
values
('<script>alert(document.cookie)</script>', '123', 1655309413840, 'zhangsan');
但是有些地方可能转义符号没有转义,例如文章详情页:
这种内容需要由前端来处理而非后端。
3. 密码加密
- 万一数据库被用户攻破,最不应该泄露的就是用户信息
- 攻击方式:获取用户名和密码,再去尝试登录其他系统
- 预防措施:将密码加密,即使拿到密码也不知道明文
加密流程:
先引入 node 自带的
crypto
模块const crypto = require("crypto");
在 utils 文件夹里新建文件,写密码加密的相关逻辑,然后通过这方法获取到密码加密后的内容,然后修改数据库中原来的明文密码。
当然这一步是不合理的,但是没有做注册和修改密码功能嘛没办法。
const crypto = require("crypto"); // 密钥 const SECRET_KEY = "kfdsjl_742938#"; // md5 加密内容 const md5 = (content) => { // 输出变成 16 进制 return crypto.createHash("md5").update(content).digest("hex"); }; // 加密函数 const genPassword = (password) => { const str = `password=${ password}&key=${ SECRET_KEY}`; return md5(str); }; module.exports = { genPassword, };
登录的时候密码加密并进行查询,因为现在数据库里存的是加密后的内容。
// controller/user.js const { exec, escape } = require("../db/mysql"); const { genPassword } = require("../utils/cryp"); const login = (username, password) => { username = escape(username); // 生成加密密码 password = genPassword(password); password = escape(password); const sql = ` select username, realname from users where username = ${ username} and password = ${ password}; `; return exec(sql).then((rows) => { return rows[0] || { }; }); }; module.exports = { login, };
4. 流程图
- 处理 http 接口
- 连接数据库
- 实现登录
- 安全
- 日志
- 上线
边栏推荐
- Drive development - the first helloddk
- Review of double pointer problems
- Please wait while Jenkins is getting ready to work
- Nacos TC setup of highly available Seata (02)
- TCP three handshakes you need to know
- [noip2009 popularization group] score line delimitation
- Using stopwatch to count code time
- [leetcode] 18. Sum of four numbers
- Modbus协议通信异常
- [leetcode daily question] number of enclaves
猜你喜欢
Nacos - TC Construction of High available seata (02)
图论的扩展
Modbus protocol communication exception
[leetcode daily question] number of enclaves
Pix2pix: image to image conversion using conditional countermeasure networks
Codeforces Round #804 (Div. 2)
Check the useful photo lossless magnification software on Apple computer
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Questions d'examen écrit classiques du pointeur
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
随机推荐
Three methods of Oracle two table Association update
Tetris
Postman test report
RT thread analysis - object container implementation and function
图数据库ONgDB Release v-1.0.3
Cuda11.1 online installation
Biscuits (examination version)
Postman manage test cases
Collection + interview questions
驱动开发——HelloWDM驱动
Drive development - the first helloddk
[leetcode16] the sum of the nearest three numbers (double pointer)
【OSPF 和 ISIS 在多路访问网络中对掩码的要求】
關於Unity Inspector上的一些常用技巧,一般用於編輯器擴展或者其他
浅谈镜头滤镜的类型及作用
Compilation et connexion de shader dans games202 - webgl (comprendre la direction)
2022 half year summary
Configuration file converted from Excel to Lua
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
[buuctf.reverse] 159_[watevrCTF 2019]Watshell