经典的浏览器安全问题

3,146 阅读8分钟

一、前言

浏览器发展了这么多年,这么多用户在使用,总不能一直是裸奔状态的。

在没有安全保障的 Web 世界中,我们是没有隐私的,因此需要安全策略来保障我们的隐私和数据的安全。

所以今天这篇就从同源策略,xss攻击、CSRF和https来讲解下浏览器的安全问题。

二、同源策略

什么是同源?什么是同源策略?

如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源。比如两个 URL,它们具有相同的协议 HTTPS、相同的域名 www.baidu.com,以及相同的端口 443,所以我们就说这两个 URL 是同源的。

浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作 DOM,那么会有一套基础的安全策略的制约,我们把这称为同源策略

同源策略会隔离不同源的 DOM、页面数据和网络通信,进而实现 Web 页面的安全性。

不过鱼和熊掌不可兼得,要绝对的安全就要牺牲掉便利性,因此我们要在这二者之间做权衡,找到中间的一个平衡点,也就是目前的页面安全策略原型。总结起来,它具备以下三个特点:

  1. 页面中可以引用第三方资源,不过这也暴露了很多诸如 XSS 的安全问题,因此又在这种开放的基础之上引入了 CSP 来限制其自由程度。
  2. 使用 XMLHttpRequest 和 Fetch 都是无法直接进行跨域请求的,因此浏览器又在这种严格策略的基础之上引入了跨域资源共享策略(CORS),让其可以安全地进行跨域操作。
  3. 两个不同源的 DOM 是不能相互操纵的,因此,浏览器中又实现了跨文档消息机制,让其可以比较安全地通信。

三、Xss攻击--跨站脚本攻击

XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。

我们来看看,如果页面被注入了恶意 JavaScript 脚本,恶意脚本都能做哪些事情:

  • **可以窃取 Cookie 信息。**恶意 JavaScript 可以通过“document.cookie”获取 Cookie 信息,然后通过 XMLHttpRequest 或者 Fetch 加上 CORS 功能将数据发送给恶意服务器;恶意服务器拿到用户的 Cookie 信息之后,就可以在其他电脑上模拟用户的登录,然后进行转账等操作。

  • 可以监听用户行为。恶意 JavaScript 可以使用“addEventListener”接口来监听键盘事件,比如可以获取用户输入的信用卡等信息,将其发送到恶意服务器。黑客掌握了这些信息之后,又可以做很多违法的事情。

  • 可以通过修改 DOM 伪造假的登录窗口,用来欺骗用户输入用户名和密码等信息。

  • 还可以在页面内生成浮窗广告,这些广告会严重地影响用户体验

那么恶意脚本是如何注入的呢?

  • 存储型 XSS 攻击

    ​ 首先黑客利用站点漏洞将一段恶意 JavaScript 代码提交到网站的数据库中;

    ​ 然后用户向网站请求包含了恶意 JavaScript 脚本的页面;

    ​ 当用户浏览该页面的时候,恶意脚本就会将用户的 Cookie 信息等数据上传到服务器。

  • 反射型 XSS 攻击

    ​ 用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端,

    Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不同的地方

  • 基于 DOM 的 XSS 攻击

    ​ 黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面传输过程中修改 HTML 页面的内容

那如何阻止这个xss的攻击呢?下面我们就看看主要的策略有哪些:

1.服务器对输入脚本进行过滤或转码
2. 充分利用 CSP
3.使用 HttpOnly 属性

由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的

四、CSRF

CSRF 英文全称是 Cross-site request forgery,是指黑客引诱用户打开黑客的网站,在黑客的网站中,利用用户的登录状态发起的跨站请求。简单来讲,CSRF 攻击就是**利用了用户的登录状态,并通过第三方的站点来做一些坏事。**而且CSRF 攻击并不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击

它主要利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

攻击方式主要有如下几种:

  • 自动发起 Get 请求
  • 自动发起 POST 请求
  • 引诱用户点击链接

这几种攻击方式的前提

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

具体流程参考下图

img

如何防范CSRF呢:

1、充分利用好 Cookie 的 SameSite 属性

Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。他可以设置三个值

1.Strict

浏览器会完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

2.Lax

在跨站点的情况下Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。包括链接,预加载请求,GET 表单。而如果在第三方站点中使用 Post 方法,或者通过 img、iframe 等标签加载的 URL,这些场景都不会携带 Cookie。

3.None

在任何情况下都会发送 Cookie 数据,最新版本的Chrome中Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

验证请求的来源站点

五、HTTPS

起初设计 HTTP 协议的目的很单纯,就是为了传输超文本文件,那时候也没有太强的加密传输的数据需求,所以 HTTP 一直保持着明文传输数据的特征。但这样的话,在传输过程中的每一个环节,数据都有可能被窃取或者篡改,这也意味着你和服务器之间还可能有个中间人,你们在通信过程中的一切内容都在中间人的掌握中。我们使用 HTTP 传输的内容很容易被中间人窃取、伪造和篡改,通常我们把这种攻击方式称为中间人攻击

鉴于 HTTP 的明文传输使得传输过程毫无安全性可言,且制约了网上购物、在线转账等一系列场景应用,于是倒逼着我们要引入加密方案。从 HTTP 协议栈层面来看,我们可以在 TCP 和 HTTP 之间插入一个安全层,所有经过安全层的数据都会被加密或者解密,你可以参考下图:

![9e99f797de30a15a11b0e4b4c8f810cf](/Users/jjn/Desktop/资料/极客时间 浏览器工作原理与实践/36 _ HTTPS:让数据传输更安全_files/9e99f797de30a15a11b0e4b4c8f810cf.png)

https是如何工作的呢?

![image-20210513194155914](/Users/jjn/Library/Application Support/typora-user-images/image-20210513194155914.png)

如上图所示:

  • 首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client-random;

  • 服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的加密套件、service-random 和公钥;

  • 浏览器保存公钥,并生成随机数 pre-master,然后利用公钥对 pre-master 加密,并向服务器发送加密后的数据;

  • 最后服务器拿出自己的私钥,解密出 pre-master 数据,并返回确认消息

服务器和浏览器就有了共同的 client-random、service-random 和 pre-master,然后服务器和浏览器会使用这三组随机数生成对称密钥,因为服务器和浏览器使用同一套方法来生成密钥,所以最终生成的密钥也是相同的。

有了对称加密的密钥之后,双方就可以使用对称加密的方式来传输数据了。

采用这种方式虽然能保证数据的安全传输,但是依然没办法证明服务器是可靠的,于是又引入了数字证书,数字证书是由 CA 签名过的,所以浏览器能够验证该证书的可靠性。

感谢


谢谢你读完本篇文章,希望对你能有所帮助,如有问题欢迎各位指正。

我是南瓜小神(✿◡‿◡),如果觉得写得可以的话,请点个赞吧❤。