我不是搞安全研究的科班出身,但前些年在业务团队做后端时,被一次线上漏洞审计折腾得够呛。从那以后我才真正意识到:所谓“黑客入侵”,绝大多数时候并不是什么高深莫测的逆向工程,而是攻击者比开发多想了半步——他们提交的数据,从来就不是你以为的那个“数据”。这篇文章想聊的,就是信息安全里最经典也最容易出事的两个入口:SQL 注入和 XSS。我会用三个真实可复现的案例,把攻击者到底是怎么“套路”网站的、每一步背后是什么原理、以及我们写代码的人应该怎么防,全部拆开讲清楚。内容适合刚接触安全的后端开发、测试同学,以及想搞明白漏洞本质的网安爱好者。不需要你有渗透基础,跟着案例走一遍,你就能看懂那些漏洞报告里最常出现的攻击路径。
1. 三个案例的整体设计与拆解思路
1.1 为什么会选这三个案例
我最初给自己定的目标是:用最少的案例,覆盖最常见的两类漏洞,同时让每个案例都能在一个普通开发者电脑上复现。筛选之后,我留下了一条“由浅入深”的线索:第一个案例是 SQL 注入里最经典的登录绕过,攻击者不需要知道任何账号密码,只需要在输入框里把 SQL 语句“改写”掉;第二个案例把 SQL 注入从“绕过”升级成“读取任意数据”,完整演示攻击者如何从一个带参数的网址开始,一步步拖走整张用户表;第三个案例切换到 XSS,而且专门选了一个很多人会忽略的 DOM 型 XSS,因为它在后端代码里可能完全没有痕迹,很多团队就是在这里栽跟头。
这三个案例的共性在于:攻击者都没有“破解”任何东西,只是把原本就该被服务端信任的输入数据,变成了自己控制的“代码”。理解这一点,比记住任何一条 payload 都重要。
1.2 案例对应的攻击面与防御视角
从攻击面来看,前两个案例都发生在服务端:一条拼接出来的 SQL 语句,被用户输入改变了语义。第三个案例发生在浏览器端:用户提交的内容被当作 HTML 或 JavaScript 执行。攻击面不同,防御重心也就完全不一样。
- SQL 注入的核心矛盾是:数据和代码没有分离。修复思路是参数化查询,让数据库永远把用户输入当作“值”而不是“SQL 片段”。
- XSS 的核心矛盾是:用户输入被当作“页面代码”输出了。修复思路是输出编码,让浏览器把它当作纯文本显示,而不是去解析执行。
所以这篇文章虽然是“讲攻击案例”,但我真正想传递的是防御视角。每个案例我都会给出修复后的代码,以及一套可以沉淀到团队规范里的检查清单。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 案例一:SQL 注入登录绕过,一行万能密码打穿后台
2.1 攻击场景还原:一个看似普通的登录框
假设有一个老旧的管理系统,登录功能的后端代码长这样:
php复制$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM admin WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// 登录成功,跳转到后台
} else {
// 登录失败
}
这段代码最大的问题,是把 username 和 password 直接用单引号拼进了 SQL 字符串里。攻击者在用户名字段输入下面这行内容:
text复制admin' OR '1'='1
拼完之后,实际执行的 SQL 就变成了:
sql复制SELECT * FROM admin WHERE username = 'admin' OR '1'='1' AND password = ''
注意,SQL 的优先级里 AND 高于 OR,所以这句查询实际是先算 '1'='1' AND password = '',然后再和 username = 'admin' 做 OR。当然这里 password 一般也不为空,但这不影响结果——'1'='1' 恒真,整个 WHERE 条件必然为真。只要 admin 这个用户存在,这条查询就会返回该用户记录,登录校验直
