XSS全称跨站脚本攻击Cross-Site Scripting是我这些年排查前端安全问题碰到最多的漏洞类型没有之一。明明页面看起来一切正常用户也没点什么奇怪的链接攻击者的脚本就能在你浏览器里悄悄跑起来偷Cookie、篡改页面、记录键盘、钓鱼几乎什么事都干得出来。这篇内容我会从攻击原理开始讲清楚再配合实际案例拆解三种XSS形态接着给出可以直接落地的防御配置和代码示例最后聊聊我踩过的一些坑和排查套路。无论你是前端开发、后端开发还是刚接触安全测试的同行这篇文章应该都能派上用场。1. XSS攻击的本质先搞懂敌人怎么进来的1.1 浏览器为什么会“信任”恶意脚本XSS产生的最底层原因是浏览器无法区分“用户主动编写的脚本”和“攻击者注入的脚本”。HTML、CSS、JavaScript全部混在同一个文档流里服务端返回什么浏览器就渲染什么它不会去问一句“这段代码你认识吗”。我习惯把这个过程比喻成一场不设防的演出服务器是舞台浏览器是观众席数据是上台的演员。正常情况下演员都是经过后台审核的。但现在某个入口比如搜索框、评论区、URL参数让普通观众也能直接往台上扔东西后台又没检查这个被扔上去的东西就会被当成正式节目展示给所有人。攻击者要做的就是让自己写的那段恶意脚本混进正常数据流里被当成“正式节目”执行。这里有一个关键点浏览器执行脚本时默认赋予的是当前页面的完整权限。也就是说恶意脚本能读取当前页面的Cookie、能修改页面内容、能向任意接口发请求而且这些操作在用户看来和页面自身的功能没有任何区别。理解了这一点就能明白为什么XSS能造成那么大的破坏——它不是在页面外面攻击这个系统它是在页面内部获得了和正常代码同等的信任。1.2 三种XSS形态一次说清根据攻击载荷的存储位置和触发方式XSS通常分成三类反射型、存储型和DOM型。很多教程喜欢从“是否经过服务端”这个维度区分这里我直接给出一个对照表方便你快速定位。类型攻击载荷存放位置触发方式典型危害检测难度反射型不在目标服务器存储藏在URL参数里需要诱导用户点击恶意链接窃取Cookie、会话劫持低存储型持久存储在服务器数据库或文件系统任何用户访问被污染页面即触发蠕虫式传播、批量窃取数据、页面篡改中DOM型完全不出现在服务端存在于前端代码逻辑中前端JavaScript读取URL等数据后动态插入页面与反射型类似但更隐蔽高反射型的问题根源在服务端接口把用户输入直接拼进了返回的HTML里没做输出编码。存储型的问题根源也在服务端用户提交的数据进入持久化存储之后在展示环节被原样渲染。DOM型最特殊问题完全出在客户端前端代码在操作DOM时把不可信数据直接交给了innerHTML、document.write这些危险API。我见过不少团队修XSS漏洞时只盯着服务端过滤输入结果DOM型漏洞连服务端日志里都看不到痕迹排查起来特别被动。所以三类都要心里有数下面逐个拆开讲。2. 攻击场景拆解漏洞到底藏在哪些常见功能里2.1 反射型XSS链接里的陷阱反射型XSS最典型的场景就是搜索页。你打开某个网站的搜索功能输入“安全测试”四个字服务端把搜索词原样回显在结果页面的标题里“你搜索的是安全测试”。如果服务端直接把URL参数拼进HTML而不做任何编码攻击者只要构造一个特殊链接就能让脚本在受害者浏览器里执行。举个例子假设搜索接口的URL长这样/search?qscriptalert(document.cookie)/script用户点击这个链接后浏览器向服务端发起请求服务端把q参数的值拼到页面里返回浏览器解析HTML时把这段script当成正常脚本执行弹窗出现。注意脚本是“反射”回来的没有留在服务器上所以每次攻击都必须让受害者点击携带载荷的链接。为什么要强调这一点因为反射型XSS的利用条件虽然苛刻要诱导点击但在一些特殊场景下危害极大。比如某些登录页面、密码重置页面如果存在反射型XSS攻击者可以构造一个看起来完全可信的同源链接配合钓鱼话术让用户输入敏感信息。我之前排查过一个案例某系统的URL参数会直接被拼接到