手把手教你防御 XSS 攻击

简介: 继上一篇文章介绍了如何实现 XSS 攻击之后,后面留下了伏笔,我们应该如何去防御文章介绍的 XSS 各种攻击呢?废话少说,直接上车!

继上一篇文章介绍了如何实现 XSS 攻击之后,后面留下了伏笔,我们应该如何去防御文章介绍的 XSS 各种攻击呢?废话少说,直接上车!

202212071826163.png

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

攻击分类

XSS 攻击主要可以分为三类

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

接下来将从上面的攻击类型分别给出防御方案

反射型

IMG

为什么叫 ta 反射型,大概是因为

由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

而像上面这个是一个搜索的例子,用户需要点击下面这个链接

http://localhost:3000/search?search=<script>alert("反射型 XSS 攻击")</script>

这个反射型 XSS 攻击之所以能够成功的原因是后端未对用户提交的内容做校验,具体逻辑如下

/**
 * 基于用户搜索内容返回 /search 页面内容
 * @param {string} search 
 */
exports.generateSearchHTML = (search = "") => {
  return `
    <body>
      <form
        action="http://localhost:3000/search"
        method="GET"
        enctype="application/json"
      >
        搜索:<input class="search-input" name="search" type="text" />
        <br />
        搜索内容:${search}
        <br />
        <button class="confirm-button" type="submit">确认</button>
      </form>
    </body>
  `;
};

此类后端渲染直接拼接返回 HTML 字符串是主要原因,所以防御的主要手段就是对可能的恶意代码片段进行转义

啥是转义呢?为什么不直接把可能是恶意代码删掉就行了呢?

比如 <script>alert("反射型 XSS 攻击")</script> 里的 < > / 这几个字符,我删掉就行了

这样操作其实不太严谨,毕竟不是所有和 < > / 相关的内容都是恶意的,就比如我数学不好,我去搜索 5 < 7 的答案是多少,很合理吧?

202212142112936.png

所以过滤和删除是不行的,所以就要采用转义

转义(Escape)

有一些特别的字符被保留用于 HTML 中,这意味着浏览器会将这些字符解析为 HTML 代码。例如,如果你使用小于号( <),浏览器会将其后的文本解析为一个  tag

HTML 有一些特殊字符,就比如 < > / 这种字符,如果你想要在浏览器展示,想要 HTML 能够正常渲染,可以采用浏览器提供的实体(Entity

比如说

<span>123&amp;</span>

实际效果就是 123&

这个转义的意思和正则表达式的转义应该是差不多的

下面这个是文章使用到的转义字符的对照表

字符 十进制 转义字符
" &#34; &quot;
& &#38; &amp;
< &#60; &lt;
> &#62; &gt;
不断开空格(non-breaking space) &#160; &nbsp;

更详细的对照表请参考下面的两个表

  1. HTML转义字符常用对照表 - OSCHINA
  2. 字符实体的官方列表 - 这个格式乱乱的,建议看上面这个

防御实操

回到反射型 XSS 攻击的防御,可以在 Server 端采用转义的方式解决,代码如下

// ...
exports.generateSearchHTML = (search = "") => {
  /**
   * 转义字符串
   * @param {string} originStr
   * @returns
   */
  const escape = (originStr) => {
    let str = originStr;
    str = str.replace(/</g, "&lt;");
    str = str.replace(/>/g, "&gt;");
    str = str.replace(/"/g, "&quot;");
    str = str.replace(/'/g, "&#x27;");
    str = str.replace(/\//g, "&#x2F;");
    return str;
  };

  return `
    ...
        搜索内容:${search}
    ...
  `;
};

我的正则应该还是非常 66666

202212142148032.png

效果如下

202212142156184.gif

直接将攻击者的恶意代码渲染,并且不会执行,看看这次生成的 HTML

<body>
  <form
    action="http://localhost:3000/v2/search"
    method="GET"
    enctype="application/json"
  >
    搜索:<input class="search-input" name="search" type="text" />
    <br />
    搜索内容:&lt;script&gt;alert(&quot;反射型 XSS
    攻击&quot;)&lt;&#x2F;script&gt;
    <br />
    <button class="confirm-button" type="submit">确认</button>
  </form>
</body>

特殊字符都被转义了,恶意代码不会被执行

存储型和 DOM 型

如果你看过这篇我的前篇文章就知道,其实所谓的 XSS 攻击的三种分类都是一样的,对前端来说就是,获取变量然后渲染,XSS 在其中就是

  1. 提交恶意代码
  2. 浏览器执行恶意代码

XSS 攻击的处理和场景辨别是一个需要经验的知识,文章不可能介绍的了全部,尽可能的防御是对需要转义的场景可以采用受业界广泛采用的库,比如 leizongmin/js-xss

npm install xss

这样库出问题的时候就大家都出问题了,法不责众,哈哈哈哈哈哈哈哈哈

但是对于 XSS 攻击的防御还有最后一个需要介绍的

转义时机

XSS 攻击步骤

  1. 提交恶意代码
  2. 浏览器执行恶意代码

前端

首先前端转义再提交后端不靠谱,攻击者只要模拟发起请求,绕过前端,后端请求处理比较靠谱

后端

对于反射型来说,不需要存入数据库,而且需要拼接字符串,但对于存储型 XSS 攻击的入库内容就不太一样,比如下面这个场景

用户提交了一个评论内容,但是如果这个获取评论的 GET 请求 iOS/Andorid/Web 都需要展示呢?

比如内容在 5 < 7

如果在存入数据库时转义,那么数据库实际存储内容就是 5 &lt; 7

那么 iOS/Andorid 端请求时并展示时就是 5 &lt; 7

而对于 Web 来说,如果有用到这个请求的某个页面有 SEO 需求做了 SSR 处理,则拼接 HTML 字符串可以正常展示,而对于有用到这个请求的某个页面是使用 Ajax 来展示,则也会显示 5 &lt; 7

具体如下图

IMG

实际操作中可以

  1. 恶意代码存储进库,保证浏览器不执行就行了,拼接 HTML 处理即可
  2. 先过滤存储,在实际多端 GET 请求时再反转义一次,比如

iOS/Android 由 5 &lt; 7 转义至 5 < 7

参考资料

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