常见网络攻击与防御
介绍
网络攻击是指利用网络漏洞和弱点,未经授权访问、使用、披露、中断、修改或破坏网络资源的行为。了解常见的网络攻击类型及其防御措施,对于保护网络安全至关重要。本章将详细介绍几种常见的网络攻击类型、攻击原理以及相应的防御措施,包括后端Node.js和前端React的具体实现示例。 网络攻击是指利用网络漏洞和弱点,未经授权访问、使用、披露、中断、修改或破坏网络资源的行为。了解常见的网络攻击类型及其防御措施,对于保护网络安全至关重要。本章将详细介绍几种常见的网络攻击类型、攻击原理以及相应的防御措施。
核心概念与原理
常见网络攻击分类
- 拒绝服务攻击(DoS/DDoS):通过大量请求耗尽目标系统资源,使其无法正常服务
- 中间人攻击(Man-in-the-Middle, MitM):拦截并可能修改通信双方之间的信息
- 跨站脚本攻击(Cross-Site Scripting, XSS):通过注入恶意脚本,在受害者浏览器中执行
- SQL注入攻击(SQL Injection):通过注入恶意SQL语句,操纵数据库
- 密码攻击:通过暴力破解、字典攻击等方式获取用户密码
- 社会工程学攻击:通过欺骗手段获取敏感信息
- 网络钓鱼(Phishing):伪装成可信实体,诱骗用户提供敏感信息
- 跨站请求伪造(Cross-Site Request Forgery, CSRF):诱导用户在已认证的网站上执行非本意的操作
- 点击劫持(Clickjacking):通过欺骗用户点击隐藏的恶意链接
- XML外部实体注入(XML External Entity, XXE):通过注入外部实体资源读取敏感文件
- 命令注入(Command Injection):通过注入系统命令获取服务器权限
- 远程代码执行(Remote Code Execution, RCE):通过漏洞执行恶意代码
- 文件上传漏洞:允许攻击者上传恶意文件到服务器
- API安全漏洞:未授权访问或滥用API接口
攻击与防御模型图示
+----------------+ +----------------+ +----------------+
| 攻击类型 | | 攻击原理 | | 防御措施 |
+----------------+ +----------------+ +----------------+
| - DDoS攻击 | | - 资源耗尽 | | - 流量清洗 |
| - 中间人攻击 | | - 通信拦截 | | - 加密通信 |
| - XSS攻击 | | - 脚本注入 | | - 输入验证 |
| - SQL注入 | | - 数据库操纵 | | - 参数化查询 |
| - 密码攻击 | | - 暴力破解 | | - 强密码策略 |
+----------------+ +----------------+ +----------------+
常见网络攻击详细介绍与防御
DDoS攻击
分布式拒绝服务攻击(DDoS)通过大量恶意流量淹没目标服务器,使其无法响应合法请求。
攻击原理
- 利用僵尸网络发送大量请求
- 消耗服务器CPU、内存或带宽资源
- 常见类型包括SYN洪水、UDP洪水、HTTP洪水等
防御措施
- 流量清洗:使用专业的DDoS防护服务过滤恶意流量
- 速率限制:限制单个IP的请求频率
- 负载均衡:分散流量到多个服务器
- CDN部署:使用内容分发网络分担流量压力
Node.js防御示例
使用express-rate-limit进行速率限制:
const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
// 限制每个IP每分钟最多100个请求
const limiter = rateLimit({
windowMs: 60 * 1000, // 1分钟
max: 100, // 每个IP最多100个请求
standardHeaders: true,
legacyHeaders: false,
});
// 应用速率限制中间件
app.use(limiter);
// 路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
跨站脚本攻击(XSS)
跨站脚本攻击(XSS)是指攻击者通过在网页中注入恶意脚本,当用户访问该页面时,脚本会在用户的浏览器中执行,从而窃取用户信息或进行其他恶意操作。
攻击原理
- 存储型XSS:恶意脚本被存储在服务器数据库中
- 反射型XSS:恶意脚本通过URL参数等方式反射给用户
- DOM型XSS:通过修改页面DOM结构执行恶意脚本
防御措施
- 输入验证:对所有用户输入进行验证和过滤
- 输出编码:对输出到页面的内容进行HTML编码
- 使用Content Security Policy(CSP):限制页面中脚本的执行
- 避免使用eval()等危险函数:防止动态执行代码
Node.js后端防御示例
使用helmet设置CSP:
const express = require('express');
const helmet = require('helmet');
const app = express();
// 设置CSP
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"] ,
scriptSrc: ["'self'", "trusted-scripts.com"],
styleSrc: ["'self'", "trusted-styles.com"],
imgSrc: ["'self'", "data:"],
connectSrc: ["'self'"] ,
fontSrc: ["'self'"] ,
objectSrc: ["'none'"] ,
mediaSrc: ["'self'"] ,
frameSrc: ["'none'"] ,
},
}));
// 路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
React前端防御示例
使用React的JSX自动转义:
import React from 'react';
export default function UserComment({ comment }) {
// React的JSX会自动转义HTML特殊字符
return (
<div className="comment">
<p>{comment.text}</p> {/* 安全:自动转义 */}
<p dangerouslySetInnerHTML={{ __html: comment.text }} /> {/* 危险:不自动转义 */}
</div>
);
}
使用CSP头部:
// 在React应用的index.html中添加CSP头部
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:">
SQL注入攻击
SQL注入攻击是指攻击者通过在用户输入中插入恶意SQL语句,从而操纵数据库,获取敏感信息或执行未授权操作。
攻击原理
- 通过用户输入注入SQL代码
- 绕过分级验证
- 访问、修改或删除数据库中的数据
防御措施
- 参数化查询:使用参数化查询或预编译语句
- 输入验证:对用户输入进行严格验证
- 最小权限原则:限制数据库用户的权限
- 错误信息控制:不向用户暴露详细的数据库错误信息
Node.js防御示例
使用参数化查询:
const mysql = require('mysql2/promise');
async function getUserById(id) {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test_db'
});
// 使用参数化查询
const [rows] = await connection.execute('SELECT * FROM users WHERE id = ?', [id]);
return rows[0];
}
跨站请求伪造(CSRF)
跨站请求伪造(CSRF)是指攻击者诱导用户在已认证的网站上执行非本意的操作,如转账、修改密码等。
攻击原理
- 用户已登录目标网站
- 攻击者诱导用户访问恶意网站
- 恶意网站向目标网站发送请求
- 目标网站误以为是用户主动操作
防御措施
- 使用CSRF令牌:为每个表单请求生成唯一令牌
- 检查Referer头部:验证请求来源
- 使用SameSite Cookie属性:限制Cookie的发送范围
- 双重提交防护:在Cookie和请求体中都包含CSRF令牌
Node.js防御示例
使用csurf中间件:
const express = require('express');
const csurf = require('csurf');
const cookieParser = require('cookie-parser');
const app = express();
// 解析cookie
app.use(cookieParser());
// 设置CSRF保护
const csrfProtection = csurf({
cookie: true
});
// 应用CSRF中间件
app.use(csrfProtection);
// 路由
app.get('/', (req, res) => {
// 传递CSRF令牌给前端
res.render('index', { csrfToken: req.csrfToken() });
});
app.post('/submit', (req, res) => {
// CSRF令牌会自动验证
res.send('Form submitted successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
React前端防御示例
在表单中包含CSRF令牌:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function CommentForm() {
const [csrfToken, setCsrfToken] = useState('');
const [comment, setComment] = useState('');
useEffect(() => {
// 获取CSRF令牌
axios.get('/csrf-token')
.then(res => {
setCsrfToken(res.data.csrfToken);
});
}, []);
const handleSubmit = (e) => {
e.preventDefault();
// 提交表单时包含CSRF令牌
axios.post('/submit-comment', {
comment: comment,
csrfToken: csrfToken
});
};
return (
<form onSubmit={handleSubmit}>
<input
type="hidden"
name="csrfToken"
value={csrfToken}
/>
<textarea
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Add a comment"
/>
<button type="submit">Submit</button>
</form>
);
}
XML外部实体注入(XXE)
XML外部实体注入(XXE)是指攻击者通过在XML输入中注入外部实体,从而读取服务器上的敏感文件或执行其他恶意操作。
攻击原理
- 应用程序接受XML输入
- 攻击者在XML中定义外部实体
- 解析器处理外部实体,读取敏感文件
- 攻击者获取敏感信息
防御措施
- 禁用外部实体解析:在XML解析器中禁用外部实体
- 使用安全的XML解析库:选择默认禁用外部实体的库
- 输入验证:对XML输入进行严格验证
- 限制解析器权限:以最低权限运行XML解析器
Node.js防御示例
禁用外部实体解析:
const xml2js = require('xml2js');
const fs = require('fs');
function parseXML(xml) {
const parser = new xml2js.Parser({
// 禁用外部实体
explicitArray: true,
normalize: true,
resolveExternals: false,
loadExternalDtd: false
});
return new Promise((resolve, reject) => {
parser.parseString(xml, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
文件上传漏洞
文件上传漏洞是指攻击者能够上传恶意文件到服务器,从而执行代码、获取敏感信息或控制服务器。
攻击原理
- 应用程序允许用户上传文件
- 攻击者上传恶意文件(如Webshell)
- 服务器执行恶意文件
- 攻击者获取服务器控制权
防御措施
- 文件类型验证:验证文件类型,不依赖文件扩展名
- 文件内容验证:检查文件内容是否符合预期
- 限制文件大小:设置上传文件大小限制
- 存储位置隔离:将上传文件存储在非Web访问目录
- 重命名文件:使用随机名称重命名上传文件
- 设置文件权限:限制上传文件的执行权限
Node.js防御示例
安全的文件上传实现:
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const app = express();
// 配置文件存储
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
// 生成随机文件名
const randomName = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
cb(null, randomName + path.extname(file.originalname));
}
});
// 文件过滤
const fileFilter = (req, file, cb) => {
// 允许的文件类型
const allowedTypes = /jpeg|jpg|png|gif|pdf/;
// 检查MIME类型
const mimetype = allowedTypes.test(file.mimetype);
// 检查文件扩展名
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
if (mimetype && extname) {
return cb(null, true);
}
cb(new Error('不支持的文件类型!'));
};
// 配置multer
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5, // 5MB
},
fileFilter: fileFilter
});
// 路由
app.post('/upload', upload.single('file'), (req, res) => {
res.send('文件上传成功');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
API安全漏洞
API安全漏洞是指API设计或实现中的缺陷,导致未授权访问、数据泄露或其他安全问题。
常见API安全问题
- 未授权访问:缺少适当的身份验证和授权
- 过度暴露:API返回过多的数据
- 注入攻击:如SQL注入、命令注入等
- 不安全的直接对象引用:通过修改参数访问未授权资源
- 缺少速率限制:容易受到暴力破解攻击
防御措施
- 身份验证与授权:使用JWT、OAuth等机制
- 输入验证:对所有API输入进行验证
- 输出过滤:限制API返回的数据
- 速率限制:防止暴力破解攻击
- API版本控制:便于安全更新
- 安全审计:记录API访问日志
Node.js防御示例
使用JWT进行身份验证:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
// 密钥,应存储在环境变量中
const SECRET_KEY = 'your-secret-key';
// 登录路由
app.post('/login', (req, res) => {
// 验证用户凭据(实际应用中应查询数据库)
const { username, password } = req.body;
if (username === 'admin' && password === 'password') {
// 生成JWT令牌
const token = jwt.sign({
username: username,
role: 'admin'
}, SECRET_KEY, {
expiresIn: '1h'
});
res.json({ token: token });
} else {
res.status(401).json({ message: '认证失败' });
}
});
// 身份验证中间件
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.status(401).json({ message: '未提供令牌' });
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.status(403).json({ message: '令牌无效' });
req.user = user;
next();
});
}
// 受保护的API路由
app.get('/api/users', authenticateToken, (req, res) => {
// 只有通过身份验证的用户才能访问
res.json([{
id: 1,
username: 'user1'
}, {
id: 2,
username: 'user2'
}]);
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
前端React安全最佳实践
以下是React应用中的一些安全最佳实践:
1. 防止XSS攻击
- 使用React的JSX自动转义功能
- 避免使用
dangerouslySetInnerHTML - 对从API获取的数据进行验证和清洗
- 实现内容安全策略(CSP)
2. 安全的状态管理
- 不在localStorage中存储敏感信息
- 使用安全的状态管理库如Redux,并加密敏感数据
- 实现适当的状态验证
3. API通信安全
- 使用HTTPS进行所有API通信
- 实现适当的身份验证和授权
- 对API响应进行验证
- 处理错误和异常情况
4. 依赖管理
- 定期更新依赖包
- 使用
npm audit或snyk检查依赖漏洞 - 避免使用已知有安全问题的库
React安全示例
安全的API请求:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function UserProfile() {
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
// 从安全存储获取令牌
const token = sessionStorage.getItem('authToken');
if (!token) {
setError('未授权访问');
return;
}
// 设置请求头
const config = {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
};
// 发送安全的API请求
axios.get('/api/user/profile', config)
.then(res => {
// 验证响应数据
if (res.data && res.data.user) {
setUser(res.data.user);
} else {
setError('无效的响应数据');
}
})
.catch(err => {
setError('获取用户信息失败');
console.error('API请求错误:', err);
});
}, []);
if (error) {
return <div className="error">{error}</div>;
}
if (!user) {
return <div>加载中...</div>;
}
return (
<div className="profile">
<h2>{user.username}</h2>
<p>邮箱: {user.email}</p>
{/* 只显示必要的信息,不暴露敏感数据 */}
</div>
);
}
命令注入攻击
命令注入攻击是指攻击者通过在用户输入中注入系统命令,从而在服务器上执行未授权操作。
攻击原理
- 应用程序接受用户输入并将其传递给系统命令
- 攻击者在输入中添加恶意命令
- 服务器执行恶意命令
- 攻击者获取服务器控制权
防御措施
- 避免使用系统命令:尽可能使用内置函数代替系统命令
- 输入验证:对用户输入进行严格验证和过滤
- 参数化:使用参数化接口传递输入
- 最小权限原则:以最低权限运行应用程序
Node.js防御示例
安全的系统命令执行:
const { execFile } = require('child_process');
const express = require('express');
const app = express();
app.use(express.json());
// 不安全的实现
app.post('/unsafe-command', (req, res) => {
const { filename } = req.body;
// 危险:直接拼接用户输入到命令中
exec(`ls -la ${filename}`, (err, stdout, stderr) => {
if (err) {
res.status(500).send(err.message);
return;
}
res.send(stdout);
});
});
// 安全的实现
app.post('/safe-command', (req, res) => {
const { filename } = req.body;
// 安全:使用execFile并传递参数数组
execFile('ls', ['-la', filename], (err, stdout, stderr) => {
if (err) {
res.status(500).send(err.message);
return;
}
res.send(stdout);
});
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
点击劫持
点击劫持是指攻击者通过欺骗用户点击隐藏的恶意链接,从而执行非本意的操作。
攻击原理
- 攻击者创建一个透明的iframe覆盖在合法网站上
- 用户点击合法网站,但实际上点击的是隐藏的恶意链接
- 用户在不知情的情况下执行恶意操作
防御措施
- X-Frame-Options头部:防止网页被嵌入到iframe中
- Content Security Policy:限制iframe的来源
- JavaScript防御:检测是否在iframe中运行
- 视觉提示:为可点击元素添加明显的视觉反馈
Node.js防御示例
设置X-Frame-Options头部:
const express = require('express');
const helmet = require('helmet');
const app = express();
// 设置X-Frame-Options
app.use(helmet.frameguard({
action: 'deny'
}));
// 路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
React前端防御示例
检测iframe环境:
import React, { useState, useEffect } from 'react';
export default function ClickjackingProtection() {
const [isIframe, setIsIframe] = useState(false);
useEffect(() => {
// 检测是否在iframe中运行
try {
setIsIframe(window.self !== window.top);
} catch (e) {
setIsIframe(true);
}
}, []);
if (isIframe) {
return (
<div className="clickjacking-warning">
<h1>警告:此网站不应在iframe中打开</h1>
<p>请直接访问我们的网站:<a href="https://example.com" target="_blank" rel="noopener noreferrer">https://example.com</a></p>
</div>
);
}
return (
<div className="normal-content">
<h1>欢迎访问我们的网站</h1>
{/* 网站内容 */}
</div>
);
}
远程代码执行(RCE)
远程代码执行(RCE)是指攻击者通过漏洞在目标系统上执行恶意代码。
攻击原理
- 应用程序存在代码执行漏洞
- 攻击者通过输入或其他方式提交恶意代码
- 应用程序执行恶意代码
- 攻击者获取系统控制权
防御措施
- 代码审计:定期进行代码审计,查找潜在漏洞
- 输入验证:对所有用户输入进行严格验证
- 避免危险函数:如eval()、exec()等
- 沙箱环境:在沙箱中执行不可信代码
- 及时更新:保持软件和依赖包的最新版本
Node.js防御示例
避免使用eval():
// 不安全的实现
function unsafeEval(userInput) {
// 危险:直接执行用户输入
return eval(userInput);
}
// 安全的实现
function safeCalculation(operation, a, b) {
// 只允许特定的操作
const operations = {
add: (x, y) => x + y,
subtract: (x, y) => x - y,
multiply: (x, y) => x * y,
divide: (x, y) => x / y
};
if (operations.hasOwnProperty(operation)) {
return operations[operation](a, b);
} else {
throw new Error('不支持的操作');
}
}
密码安全
密码安全是网络安全的基础,弱密码容易被暴力破解或字典攻击。
常见密码问题
- 使用弱密码:如'123456'、'password'等
- 重复使用密码:在多个网站使用相同的密码
- 密码存储不安全:明文或弱加密存储密码
防御措施
- 强密码策略:要求密码包含大小写字母、数字和特殊字符
- 密码哈希:使用bcrypt、Argon2等强哈希算法
- 加盐:为每个密码添加唯一的盐值
- 密码过期:定期要求用户更改密码
- 双因素认证:增加额外的认证因素
Node.js防御示例
使用bcrypt哈希密码:
const bcrypt = require('bcrypt');
const saltRounds = 10;
// 哈希密码
async function hashPassword(password) {
const salt = await bcrypt.genSalt(saltRounds);
const hash = await bcrypt.hash(password, salt);
return hash;
}
// 验证密码
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
// 示例用法
async function createUser(username, password) {
const hashedPassword = await hashPassword(password);
// 存储用户名和哈希密码到数据库
console.log(`用户 ${username} 创建成功,哈希密码:${hashedPassword}`);
}
async function loginUser(username, password) {
// 从数据库获取哈希密码
const storedHash = '...'; // 从数据库获取
const isMatch = await verifyPassword(password, storedHash);
if (isMatch) {
console.log('登录成功');
} else {
console.log('密码错误');
}
}
总结
网络安全是一个持续的过程,需要不断学习和适应新的威胁。本章介绍了常见的网络攻击类型和防御措施,并提供了Node.js后端和React前端的具体实现示例。通过采用这些安全措施,可以有效提高应用程序的安全性,保护用户数据和系统资源。
进一步学习资源
-
OWASP Top 10:https://owasp.org/www-project-top-ten/
-
Node.js安全最佳实践:https://nodejs.org/en/knowledge/security/
-
React安全文档:https://reactjs.org/docs/security.html
-
网络安全基础:https://www.coursera.org/courses?query=cybersecurity+fundamentals
中间人攻击
中间人攻击(MitM)发生在攻击者拦截并可能修改通信双方之间的信息而不被察觉的情况下。
攻击原理
- 拦截网络通信
- 伪装成通信双方信任的第三方
- 可能窃取敏感信息或修改通信内容
防御措施
- 使用HTTPS:加密传输通道
- 证书验证:验证服务器证书的有效性
- 避免使用公共Wi-Fi:公共网络容易被中间人攻击
- 使用VPN:加密所有网络流量
Node.js防御示例
在Node.js中配置HTTPS服务器:
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
// 读取SSL证书和私钥
const options = {
key: fs.readFileSync('path/to/private-key.pem'),
cert: fs.readFileSync('path/to/certificate.pem'),
ca: fs.readFileSync('path/to/ca-cert.pem'), // 可选,用于验证客户端证书
requestCert: true, // 可选,要求客户端提供证书
rejectUnauthorized: true, // 拒绝无效证书
};
// 路由
app.get('/', (req, res) => {
res.send('Secure Hello World!');
});
// 创建HTTPS服务器
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
跨站脚本攻击(XSS)
跨站脚本攻击允许攻击者将恶意脚本注入到其他用户查看的网页中。
攻击原理
- 注入恶意脚本到网页中
- 脚本在受害者浏览器中执行
- 可能窃取Cookie、会话令牌或其他敏感信息
防御措施
- 输入验证:验证所有用户输入
- 输出编码:对所有输出到HTML的数据进行编码
- 内容安全策略(CSP):限制网页可以加载的资源
- 避免使用eval():避免执行动态代码
Node.js防御示例
使用helmet设置内容安全策略:
const express = require('express');
const helmet = require('helmet');
const escapeHtml = require('escape-html');
const app = express();
// 使用helmet中间件设置安全头部
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ['\'self\''],
scriptSrc: ['\'self\'', '\'trusted-cdn.com\''],
styleSrc: ['\'self\'', 'fonts.googleapis.com'],
imgSrc: ['\'self\'', 'data:'],
fontSrc: ['\'self\'', 'fonts.gstatic.com'],
},
},
}));
// 解析请求体
app.use(express.urlencoded({ extended: true }));
// 输出编码示例
app.post('/comment', (req, res) => {
const comment = escapeHtml(req.body.comment);
// 存储评论...
res.send(`评论已发布: ${comment}`);
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
SQL注入攻击
SQL注入攻击通过将恶意SQL代码插入到查询中,操纵数据库。
攻击原理
- 通过用户输入注入恶意SQL语句
- 可能获取、修改或删除数据库中的数据
- 可能导致整个数据库被泄露
防御措施
- 参数化查询:使用参数化查询或预处理语句
- ORM框架:使用对象关系映射框架
- 输入验证:验证所有用户输入
- 最小权限原则:限制数据库用户权限
Node.js防御示例
使用mysql2进行参数化查询:
const mysql = require('mysql2/promise');
// 创建连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// 参数化查询示例
async function getUserById(id) {
try {
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [id]);
return rows[0];
} catch (error) {
console.error('Database query error:', error);
throw error;
}
}
// 使用示例
async function main() {
const user = await getUserById(1);
console.log(user);
}
main();
密码攻击
密码攻击试图通过各种方法获取用户密码。
攻击原理
- 暴力破解:尝试所有可能的密码组合
- 字典攻击:使用常见密码列表尝试
- 彩虹表攻击:使用预计算的哈希值表
- 钓鱼攻击:欺骗用户提供密码
防御措施
- 强密码策略:要求密码包含大小写字母、数字和特殊字符
- 密码哈希:使用强哈希算法存储密码
- 双因素认证:增加额外的认证因素
- 账户锁定:多次失败尝试后锁定账户
Node.js防御示例
使用bcrypt加密密码:
const bcrypt = require('bcrypt');
const saltRounds = 12;
// 加密密码
async function hashPassword(password) {
try {
const hash = await bcrypt.hash(password, saltRounds);
return hash;
} catch (error) {
console.error('Password hashing error:', error);
throw error;
}
}
// 验证密码
async function verifyPassword(password, hash) {
try {
return await bcrypt.compare(password, hash);
} catch (error) {
console.error('Password verification error:', error);
throw error;
}
}
// 使用示例
async function main() {
const password = 'SecurePassword123!';
const hash = await hashPassword(password);
console.log('Hashed password:', hash);
const isMatch = await verifyPassword(password, hash);
console.log('Password match:', isMatch);
}
main();
社会工程学攻击
社会工程学攻击利用人类心理弱点获取敏感信息。
攻击原理
- 伪装成可信实体
- 利用人类信任、恐惧或好奇心
- 可能通过电话、电子邮件或面对面交流进行
防御措施
- 安全意识培训:教育员工识别社会工程学攻击
- 验证身份:在共享敏感信息前验证对方身份
- 制定安全策略:明确信息共享规则
- 举报机制:建立攻击举报渠道
Node.js防御示例
实现安全的密码重置流程:
const express = require('express');
const crypto = require('crypto');
const nodemailer = require('nodemailer');
const User = require('./models/user');
const app = express();
// 配置邮件传输器
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'your-email@gmail.com',
pass: 'your-email-password',
},
});
// 密码重置请求
app.post('/forgot-password', async (req, res) => {
const { email } = req.body;
try {
const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({ message: '用户不存在' });
}
// 生成安全的重置令牌
const resetToken = crypto.randomBytes(32).toString('hex');
const resetTokenHash = crypto.createHash('sha256').update(resetToken).digest('hex');
// 保存令牌到数据库
user.resetPasswordToken = resetTokenHash;
user.resetPasswordExpires = Date.now() + 3600000; // 1小时后过期
await user.save();
// 发送重置邮件
const resetUrl = `http://localhost:3000/reset-password/${resetToken}`;
const mailOptions = {
to: user.email,
from: 'your-email@gmail.com',
subject: '密码重置请求',
text: `请点击以下链接重置您的密码:
${resetUrl}
如果您没有请求重置密码,请忽略此邮件。`
};
await transporter.sendMail(mailOptions);
res.status(200).json({ message: '密码重置邮件已发送' });
} catch (error) {
console.error('密码重置错误:', error);
res.status(500).json({ message: '服务器错误' });
}
});
// 密码重置
app.post('/reset-password/:token', async (req, res) => {
const { token } = req.params;
const { password } = req.body;
try {
// 哈希令牌以与数据库中的哈希值比较
const resetTokenHash = crypto.createHash('sha256').update(token).digest('hex');
// 查找有有效令牌的用户
const user = await User.findOne({
resetPasswordToken: resetTokenHash,
resetPasswordExpires: { $gt: Date.now() }
});
if (!user) {
return res.status(400).json({ message: '无效或过期的令牌' });
}
// 哈希新密码
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
// 清除重置令牌
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
await user.save();
res.status(200).json({ message: '密码已成功重置' });
} catch (error) {
console.error('密码重置错误:', error);
res.status(500).json({ message: '服务器错误' });
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
分布式拒绝服务(DDoS)攻击是指攻击者通过控制大量僵尸计算机(Botnet),向目标系统发送大量请求,耗尽目标系统的资源,使其无法正常服务。
防御措施
- 流量清洗:使用专业的DDoS防护服务,过滤恶意流量
- CDN加速:使用内容分发网络,分散流量压力
- 速率限制:限制单个IP地址的请求速率
- 负载均衡:使用负载均衡设备,分散流量到多个服务器
速率限制示例(Nginx)
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20 nodelay;
# 其他配置...
}
}
}
中间人攻击
中间人攻击是指攻击者在通信双方之间拦截并可能修改通信信息,而通信双方却不知情。
防御措施
- 使用HTTPS/TLS:加密通信通道
- 证书验证:验证服务器证书的合法性
- 避免使用公共Wi-Fi:公共Wi-Fi容易被中间人攻击
- 使用VPN:通过VPN建立安全连接
HTTPS配置示例(Nginx)
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 其他配置...
}
XSS攻击
跨站脚本攻击是指攻击者通过注入恶意脚本,在受害者浏览器中执行,窃取用户信息或执行恶意操作。
防御措施
- 输入验证:对所有用户输入进行验证和过滤
- 输出编码:对输出到页面的数据进行编码
- 内容安全策略(CSP):限制页面中可以执行的脚本
- 避免使用eval():避免使用动态执行代码的函数
输入验证示例(Java)
public class XSSFilter {
public static String filter(String input) {
if (input == null) {
return null;
}
// 移除<script>标签
input = input.replaceAll("<script.*?>.*?</script>", "");
// 转义HTML特殊字符
input = input.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll("\"", """)
.replaceAll("'", "'");
return input;
}
}
SQL注入攻击
SQL注入攻击是指攻击者通过注入恶意SQL语句,操纵数据库,获取敏感信息或执行恶意操作。
防御措施
- 参数化查询:使用参数化查询或预编译语句
- 输入验证:对所有用户输入进行验证和过滤
- 最小权限原则:限制数据库用户的权限
- 错误信息控制:避免返回详细的数据库错误信息
参数化查询示例(Java)
public class SQLInjectionExample {
public static void getUserInfo(Connection connection, String username) throws SQLException {
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, username);
ResultSet resultSet = statement.executeQuery();
// 处理结果集...
}
}
密码攻击
密码攻击是指攻击者通过暴力破解、字典攻击等方式,尝试获取用户密码。
防御措施
- 强密码策略:要求用户使用复杂密码
- 密码哈希:存储密码的哈希值,而不是明文
- 加盐哈希:对密码加盐后再进行哈希
- 多因素认证:结合多种认证方式
密码哈希示例(Java)
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;
public class PasswordHashExample {
public static String hashPassword(String password) throws Exception {
// 生成盐
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
// 加盐哈希
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
byte[] hashedPassword = md.digest(password.getBytes());
// 组合盐和哈希值
byte[] combined = new byte[salt.length + hashedPassword.length];
System.arraycopy(salt, 0, combined, 0, salt.length);
System.arraycopy(hashedPassword, 0, combined, salt.length, hashedPassword.length);
return Base64.getEncoder().encodeToString(combined);
}
public static boolean verifyPassword(String password, String storedHash) throws Exception {
byte[] combined = Base64.getDecoder().decode(storedHash);
byte[] salt = new byte[16];
System.arraycopy(combined, 0, salt, 0, salt.length);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
byte[] hashedPassword = md.digest(password.getBytes());
// 验证哈希值
for (int i = 0; i < hashedPassword.length; i++) {
if (hashedPassword[i] != combined[salt.length + i]) {
return false;
}
}
return true;
}
}
解决方案
网络攻击防护体系
- 预防:实施安全措施,防止攻击发生
- 检测:使用安全工具,及时检测攻击
- 响应:制定incident响应计划,及时处理攻击
- 恢复:在攻击后,尽快恢复系统和数据
安全监控与响应
- 安全信息和事件管理(SIEM):集中收集和分析安全事件
- 入侵检测/防御系统(IDS/IPS):检测和阻止恶意活动
- 日志分析:分析系统和应用日志,发现可疑行为
- ** incident响应团队**:组建专业的incident响应团队
最佳实践
- 定期更新和补丁:及时应用系统和软件的安全补丁
- 安全意识培训:提高员工的安全意识,减少人为失误
- 定期安全审计:定期进行安全审计,发现和修复安全漏洞
- 数据备份:定期备份重要数据,并测试恢复流程
- 最小权限原则:只授予用户完成其工作所需的最小权限
工具推荐
- Snort:开源入侵检测系统
- Suricata:高性能网络安全监测引擎
- Wireshark:网络协议分析工具
- Nessus:漏洞扫描工具
- Metasploit:渗透测试框架
- Burp Suite:Web应用安全测试工具
- OSSEC:开源主机入侵检测系统
- Fail2ban:防止暴力破解的工具