手把手教你实现 XSS 攻击

简介: XSS 攻击理论知识学习完成的同学可以参考这篇一些攻击实现,理论背的再好还是要实践呀

XSS 攻击理论知识学习完成的同学可以参考这篇一些攻击实现,理论背的再好还是要实践呀

202212071826163.png

您可以在线查看完整的示例源代码

攻击分类

XSS 攻击主要可以分为三类

  1. 存储型(持久型)(server端缺陷)
  2. 反射型(server 端缺陷)
  3. DOM 型(浏览器端缺陷)

接下来将从上面的攻击类型分别给出例子

反射型

通常一般教程先讲存储型,但是本篇文章基于实验先讲反射型,因为它和存储型有异曲同工之处,而且更底层

反射型通常出现于以下场景:常见于通过 URL 传递参数的功能,如网站搜索、跳转等

接下来就给出一个网站搜索的例子

下面是一个很常见的 search 页面例子

<!-- search.html -->
<body>
  <form
    action="http://localhost:3000/search"
    method="GET"
    enctype="application/json"
  >
    搜索:<input class="search-input" name="search" type="text" />
    <br />
    搜索内容:
    <br />
    <button class="confirm-button" type="submit">确认</button>
  </form>
</body>

效果如下

IMG

IMG

注意 搜索内容: 这部分的 DOM 内容以及 URL 的参数 search,这两个点其实就是 XSS 攻击的突破口

突破口

上面这个网站是一个由后端渲染的网站,那么它是怎么渲染的呢?

// user.js
router.get("/search", function (req, res, next) {
  const { search } = req.query;
  res.setHeader("Content-Type", "text/html");
  res.send(generateSearchHTML(search));
});
exports.generateSearchHTML = (search = "") => {
  return `
    .....
        搜索内容:${search}
    .....
  `;
};

其中 generateSearchHTML 将基于上面给出的 HTML 模板生成 HTML 文件内容,并返回给用户,并且会将用户输入的搜索内容,即 search 填充的 HTML 模板中,即 搜索内容:${search}

回到 XSS 攻击的本质就是执行恶意代码,换言之就是 <script></script> 的执行,回到上面的模板,如果转换成下面的结构,请问 <script></script> 是否会执行?

<body>
  搜索内容:<script></script>
</body>
<script></script>

不要拘束与传统的三段式写法而以为 <body> 中的脚本不会执行,上面的代码能够顺利执行,因此执行 XSS 攻击的关键就是编写代码到搜索框中,后台返回给用户时即完成 XSS 攻击,实操如下

  1. 输入 <script>alert("反射型 XSS 攻击")</script>
  2. 确认

反射型的 XSS 攻击我曾经在一个卖民用机械的网站上见过,技术栈估计是 JSP + SpringBoot 一把梭,其中的搜索框就有这个问题

那么如何吸引用户完成这个攻击呢?其实吸引用户点击具有上面这个 url 构成的链接即可,并不需要用户亲自去输入

存储型

了解到上面反射型的 XSS 攻击,我相信你们对 XSS 攻击已经有了初步了解,被攻击的原因是没有对用户的输入做任何处理就作为 HTML 的一部分返回,所以存储型的攻击也可以以此为基础

后端渲染

后端渲染,即由后端返回 HTML

存储型 XSS 攻击原理还是一样,像服务端传输恶意代码,并且服务端会将其拼接至字符串中

被攻击网站如下

202212131912114.gif

简单的 HTML 代码

<body>
  评论:<span class="comment"></span>
  <input class="comment-input" type="text" style="display: none" />
  <br />
  <button class="button" onclick="handleModifyComment()">新增评论</button>
  <button
    class="confirm-button"
    onclick="confirmModifyComment()"
    style="display: none"
  >
    确认
  </button>
</body>
<script>
  const comment = document.querySelector(".comment");
  const commentInput = document.querySelector(".comment-input");
  const button = document.querySelector(".button");
  const confirmButton = document.querySelector(".confirm-button");
  const getComment = () => {
    // ..
  };
  const handleModifyComment = () => {
    // ...
  };
  const confirmModifyComment = () => {
    // ...
  };

  // 初次加载
  getComment();
</script>

后端代码

router.get("/v1/user", function (req, res, next) {
  const [name, setName] = useName();

  res.setHeader("Content-Type", "text/html");
  res.send(generateHTML(name));
});

router.get("/v1/name", function (req, res, next) {
  const [name, setName] = useName();

  res.send(name);
});

router.post("/v1/name", function (req, res, next) {
  const [name, setName] = useName();
  const { username: updateName } = req.body;

  res.send(setName(updateName));
});

// ../utils/util
exports.generateHTML = (username) => {
  return `
    <body>
      username: ${username}
    </body>
  `;
};

用一个闭包模拟存储(很合理吧?)

let originName = "杰尼龟";

const useName = () => {
  const name = originName;
  /**
   * 重新赋值用户名称
   * @param {string} [newName="杰尼龟"]
   */
  const setName = (newName = "杰尼龟") => {
    originName = newName;
    return originName;
  };

  return [name, setName];
};

module.exports = useName;

实操如下,基于用户名称一个致命的恶意代码

<script>alert("XSS 攻击")</script>

IMG

说实话,存储型 XSS 攻击的场景出现在展示部分(比如用户的评论、用户名称、用户信息。。。)在新的网站都少了很多,展示部分的 XSS 攻击更可能出现在后端渲染的网站上,因为后端渲染是通过拼接字符串成 HTML 然后再返回

前端渲染不必多说,Vue/React/Angular 都是前端渲染的代表,它们以 JS 为基础渲染,渲染和更新通过 Ajax 来实现,而底层是通过 Node.innerText | Node.innerHTML 此类的方法渲染和更新页面

而浏览器会将通过 Node.innerText | Node.innerHTML 动态插入的内容当成普通文本,不会维护到DOM里面,XSS 攻击自然也无从谈起,因为无法执行

不过不要以为新网站没有 XSS 攻击,像 Nuxt.jsNext.js 这些 SSR 框架其实就是后端渲染(服务端渲染),本质上也是 HTML 拼接,不过此类开源框架往往有避免手端

前端渲染

前面说过了前后端分离的情况下,大部分数据都是通过 Ajax 拿到的,而且框架会帮我们通过 Node.innerText | Node.innerHTML 这种方式渲染,不会有 XSS 攻击的可能,但这并不意味着前端渲染并不会有被攻击的危险,比如直接渲染字符串

Vue 中提供了一个指令,叫 v-html文档里很明确的指出了具有 XSS 攻击,但像我这种文档仅供 API 参考的人,当时完全没在意,但到后来背八股文的时候发现其潜在的危险性

比如下面这个富文本的例子

IMG

像现在市面上的富文本编辑器有的可以添加链接并展示(很合理吧?富文本编辑器应该还是很常见的)

<!-- http://localhost:3000/richText.html -->
<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
</head>
<body>
  <div id="app">
    <div>
      来吧展示!
      <div class="richText" v-html="richText"></div>
    </div>
    <br />
    <button @click="addLink">添加链接</button>
  </div>
</body>
<script>
  const app = new Vue({
    el: "#app",
    data() {
      return {
        richText: "<h1>Hello World</h1>",
      };
    },
    methods: {
      addLink() {
        const linkDialog = prompt("请输入链接", "");
        if (linkDialog !== null && linkDialog !== "") {
          this.richText += `<a href=${linkDialog}>一个你无法拒绝点击的链接名称</a>`;
        }
      },
    },
  });
</script>

假设啊假设啊,添加链接后会把 <a href=${linkDialog}>一个你无法拒绝点击的链接名称</a> 传入到后端,等用户下次访问 richText.html 就直接渲染后端返回的字符串,大概就是上面这个情况

如果我把链接变成下面这种

  1. javascript:alert(&#x27;XSS&#160;攻击&#x27;)
  2. '' onclick=alert(&#x27;XSS&#160;攻击&#x27;)

PS:&#x27; 表示 "(引号),&#160; 表示 (空格),皆为 HTML 编码,HTML 可以直接渲染,v-html 使用引号和空格需要转义,详情参考html中常见符号的代码表示

IMG

芭比Q了,被攻击了

上面的 12 两条恶意代码的渲染 DOM 结构如下

1

IMG

2

202212132138697.png

1 是利用浏览器 <a>href 的特性,而 2 是利用空格间断属性,和 SQL 注入都是同根同源的操作呀!

DOM 型

阅读完反射型和存储型其实你应该已经明白,所谓 XSS 攻击就是寻找具有直接渲染和注入恶意代码的漏洞

回到 DOMXSS 攻击和存储型以及反射型的区别,区别为 DOMXSS 攻击为浏览器端缺陷,无需后端交互,即为前端代码的缺陷,其实也就是前端过于相信用户内容,直接渲染

而如果把存储型里的前端渲染的 XSS 攻击例子,想象成预览富文本不就是 DOM 型攻击咯(绝对不是我偷懒!)

总结

从反射型到存储型再到 DOM 型,我一开始找例子发现都是使用 JSP 的旧网站才会有 XSS 攻击漏洞,我想是不是前后端分离的现在已经不会有 XSS 攻击了,但随着我进一步深入,发现 SSR 和富文本场景也会有 XSS 攻击的可能,这些场景对我来说其实算是新兴的前端方向(至少相对于 JSP),所以也许 XSS 攻击从未离开我们

参考资料

  1. 前端安全系列(一):如何防止XSS攻击?
  2. 原始 HTML - Vue2 Doc
  3. html中常见符号的代码表示
  4. web安全之XSS实例解析
相关文章
|
11天前
|
JavaScript 安全 前端开发
同源策略如何防止 XSS 攻击?
【10月更文挑战第31天】同源策略通过对 DOM 访问、Cookie 访问、脚本执行环境和跨源网络请求等多方面的严格限制,构建了一道坚实的安全防线,有效地防止了 XSS 攻击,保护了用户在网络浏览过程中的数据安全和隐私。
78 49
|
4月前
|
存储 安全 JavaScript
手摸手带你进行XSS攻击与防御
当谈到网络安全和信息安全时,跨站脚本攻击(XSS)是一个不可忽视的威胁。现在大家使用邮箱进行用户认证比较多,如果黑客利用XSS攻陷了用户的邮箱,拿到了cookie那么就可以冒充你进行收发邮件,那真就太可怕了,通过邮箱验证进行其他各种网站的登录与高危操作。 那么今天,本文将带大家深入了解XSS攻击与对应的防御措施。
|
16天前
|
安全 前端开发 Java
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第26天】Web安全是现代软件开发的重要领域,本文深入探讨了XSS和CSRF两种常见攻击的原理及防御策略。针对XSS,介绍了输入验证与转义、使用CSP、WAF、HTTP-only Cookie和代码审查等方法。对于CSRF,提出了启用CSRF保护、设置CSRF Token、使用HTTPS、二次验证和用户教育等措施。通过这些策略,开发者可以构建更安全的Web应用。
51 4
|
15天前
|
安全 Go PHP
Web安全进阶:XSS与CSRF攻击防御策略深度解析
【10月更文挑战第27天】本文深入解析了Web安全中的XSS和CSRF攻击防御策略。针对XSS,介绍了输入验证与净化、内容安全策略(CSP)和HTTP头部安全配置;针对CSRF,提出了使用CSRF令牌、验证HTTP请求头、限制同源策略和双重提交Cookie等方法,帮助开发者有效保护网站和用户数据安全。
43 2
|
17天前
|
存储 安全 Go
Web安全基础:防范XSS与CSRF攻击的方法
【10月更文挑战第25天】Web安全是互联网应用开发中的重要环节。本文通过具体案例分析了跨站脚本攻击(XSS)和跨站请求伪造(CSRF)的原理及防范方法,包括服务器端数据过滤、使用Content Security Policy (CSP)、添加CSRF令牌等措施,帮助开发者构建更安全的Web应用。
50 3
|
10天前
|
SQL 存储 安全
什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?
理解并防范XSS、SQL注入和CSRF攻击是Web应用安全的基础。通过采用严格的输入验证、使用安全编码实践以及实现适当的身份验证和授权机制,可以有效防止这些常见的Web攻击,保障应用程序和用户的数据安全。
19 0
|
2月前
|
存储 安全 JavaScript
XSS跨站脚本攻击详解(包括攻击方式和防御方式)
这篇文章详细解释了XSS跨站脚本攻击的概念、原理、特点、类型,并提供了攻击方式和防御方法。
330 1
|
1月前
|
存储 JavaScript 安全
|
1月前
|
存储 JavaScript 前端开发
Xss跨站脚本攻击(Cross Site Script)
Xss跨站脚本攻击(Cross Site Script)
|
4月前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
89 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!