网络安全
1. Web 安全攻击与防御
1.1 XSS (跨站脚本攻击)
反射型 XSS
// 攻击示例
http://example.com/search?q=<script>alert('XSS')</script>
// 防御方法
function escapeHtml(str) {
return str.replace(/[&<>"']/g, function(match) {
const escape = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return escape[match];
});
}
存储型 XSS
// 攻击示例
const comment = '<img src="x" onerror="alert(document.cookie)">';
// 防御方法
// 1. 输入过滤
const sanitize = require('xss');
const safeComment = sanitize(comment);
// 2. CSP 策略
Content-Security-Policy: default-src 'self'
DOM型 XSS
// 攻击示例
location.hash = '<script>alert(1)</script>';
document.write(location.hash.substring(1));
// 防御方法
// 1. 避免使用 innerHTML、document.write
element.textContent = userInput;
// 2. 使用 DOMPurify
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirty);
1.2 CSRF (跨站请求伪造)
攻击原理
<!-- 攻击示例 -->
<form action="http://bank.com/transfer" method="POST">
<input type="hidden" name="account" value="hacker"/>
<input type="hidden" name="amount" value="10000"/>
</form>
<script>document.forms[0].submit();</script>
防御方法
// 1. Token 验证
const csrfToken = generateToken();
// 在表单中添加 token
<input type="hidden" name="_csrf" value="${csrfToken}">
// 2. 验证 Referer
app.use((req, res, next) => {
const referer = req.headers.referer;
if (isValidReferer(referer)) {
next();
} else {
res.status(403).send('Invalid referer');
}
});
// 3. SameSite Cookie
Set-Cookie: session=123; SameSite=Strict
1.3 SQL 注入
攻击示例
-- 1. 基本注入
SELECT * FROM users WHERE username = 'admin' OR '1'='1'
-- 2. 联合查询注入
SELECT * FROM users WHERE id = '1' UNION SELECT username,password FROM admin--'
-- 3. 时间盲注
SELECT * FROM users WHERE id = '1' AND IF(SUBSTR(database(),1,1)='a',SLEEP(5),0)
防御方法
// 1. 参数化查询
const sql = 'SELECT * FROM users WHERE id = ?';
connection.query(sql, [userId]);
// 2. ORM
const user = await User.findOne({
where: { id: userId }
});
// 3. 输入验证
function validateUserId(id) {
return /^\d+$/.test(id);
}
2. 加密技术
2.1 对称加密
// AES 加密示例
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
return {
iv: iv.toString('hex'),
encrypted,
authTag: authTag.toString('hex')
};
}
function decrypt(encrypted, key, iv, authTag) {
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'hex'));
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}