XSS跨域脚本攻击 和 CSRF跨站请求伪造攻击

Posted by CodingWithAlice on May 7, 2021

XSS跨域脚本攻击 和 CSRF跨站请求伪造攻击

  • 总结

    1、页面安全问题 的主要原因就是浏览器为 同源策略 开的两个后门:

    • 页面中可以任意引用 第三方资源
    • 通过 CORS 策略让 XMLHttpRequestFetch跨域 请求资源

    2、为了解决这些问题:

    • 引入了 CSP内容安全策略 来限制页面任意引入外部资源
    • 引入了 HttpOnly 机制来禁止 XMLHttpRequest 或者 Fetch 发送一些关键 Cookie
    • 引入了 SameSiteOrigin 来防止 CSRF 攻击

XSS跨域脚本攻击

XSS攻击 Cross Site Script :即 跨域脚本攻击(为和CSS区分,改叫XSS)

  • 总结

    1、XSS 攻击就是黑客往页面中注入恶意脚本,使之在客户端运行,然后将页面的一些重要数据上传到恶意服务器

    2、常见的三种 XSS 攻击模式是 存储型 XSS 攻击、反射型 XSS 攻击和 基于 DOM 的 XSS 攻击

    • 共同点

      都是需要 往用户的页面中注入恶意脚本,然后再通过恶意脚本将用户数据上传到黑客的恶意服务器上

    • 不同点

      在于 注入的方式不一样,有通过服务器漏洞来进行注入的,还有在客户端直接注入的

    3、针对这些 XSS 攻击,主要有三种 防范策略

    • 1、通过 服务器 对输入的内容进行 过滤或者转码
    • 2、充分利用好 CSP内容安全策略
    • 3、使用 HttpOnly 来保护重要的 Cookie 信息

1、反射型 — 恶意链接

  • 【简单描述】

    将用户输入的存在 XSS 攻击的数据,发送给后台,后台并未对数据进行存储,也未经过任何过滤,直接返回给客户端,被浏览器渲染

  • 【具体步骤】

    1、构造出包含恶意代码的 url,url 指向目标网站,参数拼接恶意代码,举例如下:

    image-20210507105832153

    2、诱导用户点击,点击后会向服务端发送请求,同时查询参数携带恶意代码

    3、服务端返回时 将恶意代码直接拼接在HTML

    4、客户端接收并解析执行代码时,恶意代码也被执行

  • 【特点】

    需要攻击者诱使用户操作:点击一个恶意链接/提交一个表单/进入一个恶意网站

  • 【常见场景】

    通过 URL 传递参数的场景,如 网站搜索、跳转

2、存储型

  • 【简单描述】

    数据库中存有存在XSS攻击的数据,返回给客户端,数据未经任何转义被浏览器渲染

  • 【具体步骤】

    1、把恶意代码提交到服务器端

    2、当浏览器向服务器请求数据时,恶意代码拼接在HTML中 从服务器传回

    3、客户端解析时被执行恶意代码,将用户 Cookie 信息等数据上传到恶意服务器

  • 【特点】

    这种 XSS 攻击具有 很强的稳定性

  • 【常见场景】

    论坛发帖、商品评论、用户私信 等,攻击者发布包含恶意 JS 代码的评论,所有访问的用户的浏览器中会被执行这段恶意的 JS 代码

    image-20210507110126121

3、基于 DOM 的 XSS 攻击

  • 【特点】

    通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。

  • 【可能性】

    1、<script> 标签

    2、a 标签的 hrefimgsrc,例如:<img src="javascript:alert('XSS')” />

    3、innerHTML/outerHTML=xxsetTimeout/setInterval (执行js)

    4、document.writeeval

    5、locationonclickonerroronloadonmouseover 等事件(执行js),例如:<img src="#" onerror=“alert('1')" />

    6、在 style 属性中,包含类似 background-image:url(“javascript:alert('XSS')”); 的代码(新版本浏览器已经可以防范)

    7、在 style 属性和标签中,包含类似 expression(…) 的 CSS 表达式代码(新版本浏览器已经可以防范)

XSS 攻击解决方案

无论是何种类型的 XSS 攻击,它们都有一个 共同点,那就是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上

我们可以通过阻止【恶意 JavaScript 脚本的注入】和【恶意消息的发送】来实现

XSS 攻击解决方案 详细说明 解决问题
防范反射型、存储型 XSS 1、采用纯前端渲染
2、拼接 HTML 时,要对 HTML 进行充分转义(过滤 <script> 标签,或者转码 <script> —> &lt;script&gt;
即使这段脚本返回给页面,页面也不会执行这段脚本
防范 DOM 型 XSS 1、将用户输入插入 HTML 或拼接 js 执行时,要进行编码,将一些特殊字符转义
2、对于 a 标签的 href 等外链请求,添加 白名单 进行过滤,禁止以 javascript: 开头的链接,和其他非法的 scheme
 
内容安全策略 CSP 内置于浏览器,只信任 白名单网站 详解见下方 核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码,大大减少XSS攻击
HttpOnly 标准 (防止劫取 Cookie) (HttpOnly是服务器通过响应头来设置的) 浏览器禁止页面的 JS 访问带有 HttpOnly 属性的 Cookie image-20210507111719291 攻击者通过注入恶意脚本获取用户的 Cookie 信息,发起 Cookie劫持攻击;HttpOnly 【阻止 XSS 攻击后的 Cookie 劫持攻击】
用户的输入检查 (XSS Filter) 不要相信用户的任何输入,要进行检查、过滤和转义 检查用户输入中是否包含 <,> 等特殊字符,如果存在,则对特殊字符进行 过滤或编码
服务端输出检查 除富文本的输出外,在变量输出到 HTML 页面时,可以使用 编码或转义 的方式来防御 XSS 攻击  

【踩坑汇总】内容安全策略 CSP

现在主流的浏览器内置了 CSP,它的实现/执行全部 由浏览器完成,开发者只需配置。

【CSP 实质】

白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。

【CSP 作用】

  • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的
  • 禁止向第三方域提交数据,这样用户数据也不会外泄
  • 禁止执行 内联脚本未授权的脚本
  • 还提供了 上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题

启用后,不符合 CSP 的外部资源就会被阻止加载,报错截图如下:

image-20210507112712103

实际案例:

访问 www.shemore.cn 时,由于请求了 m.beidianyx.com 下的文件,出现了报错

image-20210507112753156

1、需要把当前域名配置入 Content-Security-Policy 中 比如水梦露官网的新域名:www.shemore.cn m.beidianyx.com

2、如果 route 的配置的地址和当前页面路径不一致时,需要手动在 controller 中配置静态资源路径 ctx.state.path

【启用 CSP的两种方法】

1、HTTP 响应头 Content-Security-Policy

image-20210507112947501

2、网页的 <meta> 标签

image-20210507113015381

属性值 描述
default-src ‘self’ 用来设置下面图中各个选项的默认值 限制所有的外部资源,都只能从当前域名加载
script-src ‘self’ 脚本:只信任当前域名
child-src https: 框架(frame):必须使用 HTTPS 协议加载
report-uri 告诉浏览器,应该把注入行为报告给哪个网址

跨站请求伪造 CSRF

Cross Site Request Forgery,攻击者借助受害者的 Cookie 骗取服务器的信任以操作服务端数据

–> 改变在服务端的数据,而非窃取数据

  • 总结

    1、要发起 CSRF 攻击需要具备三个条件

    • 目标站点存在【漏洞】
    • 用户要【登录】过目标站点
    • 黑客需要通过【第三方站点】发起攻击

    2、如何防止 CSRF 攻击,主要有三种方式:

    • 充分利用好 Cookie 的 SameSite 属性

    • 验证请求的 来源站点

    • 使用 CSRF Token

  • 【特点】

    1、不能拿到 Cookie,也看不到 Cookie 的内容,仅仅是 冒用

    2、向服务器提交操作,但是不直接窃取数据,对于 服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析

    3、攻击一般发起在 第三方网站,而不是被攻击的网站;被攻击的网站无法防止攻击发生

  • 【步骤】

    1、用户登录受信任网站A,并在本地生成 Cookie

    2、在 不登出A的情况下,访问危险网站B

  • 【实现方式】

    1、打开黑客的站点后 自动发起 Get/POST 请求

    2、引诱用户点击黑客站点上的链接

  • 【案例】

    跨站请求可以用各种方式:图片URL、超链接、CORS(跨域资源共享)、Form提交等等;

    受害者登录 a.com,并保留了登录凭证(Cookie)–> 攻击者引诱受害者访问了 b.com –> b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带 a.com 的 Cookie –> a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求 –> a.com 以受害者的名义执行了 act=xx –>攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作。

image-20210507113716466

跨站请求伪造 CSRF 防范措施

方式 解析
验证码
【体验差】
【优点:最简洁而有效的防御方法 —辅助手段,不能给所有操作加验证码】 强制用户必须与应用进行交互,才能完成最终请求
同源验证 Referer Check,HTTP 请求头中的一个字段 【Referer 记录了该 HTTP 请求的来源地址】image-20210507113804487
服务端通过 Referer 可以检查请求 是否来自合法的源if (req.headers.referer !== 'http://www.c.com/') { res.write('csrf 攻击’); return;}
Cookie 的 SameSite 属性 (在 HTTP 响应头中,通过 set-cookie 字段设置 Cookie 时,可以带上 SameSite 选项) 禁止Cookie的发送
如果是从第三方站点发起的请求,那么需要浏览器禁止发送某些关键 Cookie 数据到服务器
添加 token 验证 【工作量大】 【关键在于 在请求中放入攻击者所不能伪造的信息,并且不存储于 Cookie 之中】服务器生成一个 Token,并把这个 Token 利用算法加密,加密后的字符串植入到页面 session中。在页面加载时,在每个 a 标签和form标签中放入 Token 服务器验证 Token是否正确
双重Cookie验证 【优点:无需使用Session,易于实施,可以在前后端统一拦截校验】
【缺点:Cookie 中增加了额外的字段,如果有 XSS 攻击,该防御失效,使用该方案时确保整站HTTPS的方式】
利用 CSRF 攻击不能获取到用户 Cookie 的特点,我们可以要求请求携带一个Cookie中的值。在用户访问网站页面时,向请求域名注入一个 Cookie,内容为随机字符串。在前端向后端发起请求时,取出 Cookie,并添加到 URL 的参数中。后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。