浏览器知识补充

467 阅读6分钟

前言

本文作为作者学习内容,会持续更新,主要是补充自己的浏览器&http知识体系,供大家参考,如果有不同的想法,欢迎大家留言区提出。

XSS攻击

xss攻击是指浏览器中执行恶意脚本。从而导致用户信息泄露。 恶意脚本可以做那些事:

  • 窃取cookie信息
  • 监听用户行为,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器
  • 通过修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息
  • 在页面内生成浮窗广告,这些广告会严重地影响用户体验

恶意脚本注入的三种方式

储存型 XSS攻击

这种类型是将恶意脚本存储到了服务端,然后客户端执行这些脚本,从而达到攻击的效果。
例如2015 年喜马拉雅就被曝出了存储型 XSS 漏洞。用户在设置专辑名称时,对关键字过滤不严格,用户可以输入script内容,从而导致用户点击专辑后,从而获取到用户的cookie信息。

反射型 XSS攻击

恶意脚本网络请求的一部分。

http://localhost:3000/?xss=<script>alert('你被攻击了')</script>

用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端,这就是反射型 XSS 攻击。 与存储型XSS攻击不同的是,服务器端不会储存恶意脚本。

基于DOM 型 XSS攻击

不会牵扯到服务器端。通过各种手段将恶意脚本注入到用户的页面中。
这样的劫持方式有很多:WIFI路由器劫持、本地恶意软件等。它们的共同点是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。

阻止XSS攻击

对输入脚本进行过滤或转码

将关键字符和符号进行转码编译,就不会再执行恶意脚本。
<script>编译为&lt;script&gt;,恶意脚本中的内容也不会被执行了。

利用HttpOnly

如果cookie中设置了HttpOnly属性,那么通过js脚本无法获取到cookie,这样能有效的防止XSS攻击。

CSP网页安全政策

Content Security Policy,缩写 CSP
CSP实质就是白名单制度,明确告诉客户端,哪些外部资源可以加载,等于提供一个白名单,它的实现和执行全部由浏览器完成,开发者只是提供配置。
www.ruanyifeng.com/blog/2016/0…

  1. 限制其他域下的资源加载。
  2. 禁止向其它域提交数据。
  3. 禁止执行内联脚本和未授权的脚本
  4. 提供上报机制,能帮助我们及时发现 XSS 攻击。

CSRF攻击

“别点那个链接,小心有病毒”
CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求,从而可以做一些坏事。
和 XSS 不同的是,CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。

攻击流程
1.用户打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B(跳转页面是会携带cookie信息的);
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行(比如转账)。

实现CSRF攻击的三种方式

自动发送GET请求

<img src="https://×××.com/api?user=hacker&ip=122" />

用户登录过的安全页面,进入恶意页面后,页面自动加载,浏览器会自动发起img请求资源,自动发送了 get 请求,这个请求会自动带上关于 xxx.com 的 cookie 信息(如果你已经在 xxx.com 中登录过)。
如果服务器端没有对请求做出判断的话,它可能认为发请求的是一个正常的用户,因为携带了相应的 cookie,然后进行相应的各种操作,可以是转账汇款以及其他的恶意操作。

自动POST请求

<!-- 自动提交脚本 -->
<form id='hacker-form' action="https://xxx.com/info" method="POST">
  <input type="hidden" name="user" value="hhh" />
  <input type="hidden" name="number" value="100" />
</form>
<script>document.getElementById('hacker-form').submit();</script>

在页面中构建了一个隐藏的表单,用户打开页面后,表单会自动被执行,然后请求a网站的接口,进行一些操作。

引诱用户点击链接

<a href="https://xxx/info?user=hhh&number=100" taget="_blank">点击查看美女图片</a>

点击后,自动发送 get 请求,接下来和自动发 GET 请求部分同理。

发起CSRF攻击的三个必要条件

• 目标站点一定有CSRF漏洞
• 用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态
• 需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛

防止CSRF攻击方法

利用Cookie的SameSite属性

CSRF 攻击都是从第三方站点发起的,要防止 CSRF 攻击,我们最好能实现从第三方站点发送请求时禁止 Cookie 的发送,因此在浏览器通过不同来源发送 HTTP 请求时,有如下区别:
• 如果是从第三方站点发起的请求,那么需要浏览器禁止发送某些关键 Cookie 数据到服务器;
• 如果是同一个站点发起的请求,那么就需要保证 Cookie 数据正常发送。 Cookie 的SameSite属性用来限制第三方 Cookie。

set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none

SameSite可以设置为三个值,StrictLaxNone
a. Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
b. 在Lax模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。
c. 在None模式下,也就是默认模式,请求会自动携带上 Cookie。

验证来源站点

在服务器端验证请求来源的站点.由于 CSRF 攻击大多来自于第三方站点,因此服务器可以禁止来自第三方站点的请求。

这就需要要用到请求头中的两个字段: OriginReferer
Referer 是 HTTP 请求头中的一个字段,记录了该 HTTP 请求的来源地址;虽然可以通过 Referer 告诉服务器 HTTP 请求的来源,但是有一些场景是不适合将来源 URL 暴露给服务器的,因此浏览器提供给开发者一个选项,可以不用上传 Referer 值,具体可参考 Referrer Policy。
Origin 属性只包含了域名信息,并没有包含具体的 URL 路径,这是 Origin 和 Referer 的一个主要区别。Origin 的值之所以不包含详细路径信息,是有些站点因为安全考虑,不想把源站点的详细路径暴露给服务器。

服务器的策略是优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值。 当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差。

CSRF Token

CSRF Token一般可以分为两步: 第一步,在浏览器向服务器发起请求时,服务器生成一个 CSRF Token(服务器生成的字符串)。然后将该字符串植入到返回的页面中。

<!DOCTYPE html>
<html>
<body>
    <form action="https://time.geekbang.org/sendcoin" method="POST">
      <input type="hidden" name="csrf-token" value="nc98P987bcpncYhoadjoiydc9ajDlcn">
      <input type="text" name="user">
      <input type="text" name="number">
      <input type="submit">
    </form>
</body>
</html>

第二步,在浏览器端要发送请求,就必须带上 CSRF Token,然后服务器会验证该 Token 是否合法。如果是从第三方站点发出的请求,那么将无法获取到 CSRF Token 的值,所以即使发出了请求,服务器也会因为 CSRF Token 不正确而拒绝请求。

点击劫持攻击

点击劫持是⼀种视觉欺骗的攻击⼿段。攻击者将需要攻击的⽹站通过 iframe 嵌套的⽅式嵌⼊⾃⼰的⽹⻚中,并将 iframe 设置为透明,在⻚⾯中透出⼀个按钮诱导⽤户点击。

防范措施

判断当前窗口是不是顶层窗口

网站1
    <script>
        // self 是对当前窗口自身引用 与window属性是等价的
        // top返回顶层窗口  即浏览器窗口
        // 判断的是self与top是不是都指向的window对象,如果是被iframe引用的话,top值是报错的。
        if(self === top){
            // 随意展示
        }else{
            document.body.innerHTML='hi!我的页面是不允许iframe访问的'
            // top.location = self.location   // 返回网站1这个网页
        }
    </script>

X-FRAME-OPTIONS响应头

X-FRAME-OPTIONS是⼀个 HTTP 响应头。这个 HTTP 响应头就是为了防御⽤ iframe嵌套的点击劫持攻击。
该响应头有三个值可选,分别是:

  • DENY,表示⻚⾯不允许通过 iframe 的⽅式展示
  • SAMEORIGIN,表示⻚⾯可以在相同域名下通过 iframe 的⽅式展示
  • ALLOW-FROM,表示⻚⾯可以在指定来源的 iframe 中展示