浏览器安全分为页面安全、系统安全、网络安全
页面安全
为了页面安全浏览器引入了最核心的安全策略:同源策略(Same-origin policy)
同源策略
同源指:URL的协议、域名和端口都相同。两个不同的源之间若想要相互访问资源或者操作 DOM,会有一套安全策略的制约,这就是同源策略,制约表现在三方面
- DOM方面:限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。
- 数据方面:限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。
- 网络方面:限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。
过于严格的限制会给开发带来很大的阻碍,基于安全和便利的权衡,同源策略在安全性方面做出以下三点妥协:
- 页面可以嵌入第三方资源:包括JS、HTML、CSS、图片等静态资源,所以我们才可以通过CDN来给服务器分压。但同时带来XSS漏洞。
- 跨域资源共享CORS:允许浏览器向跨源服务器发出XHR请求。整个CORS通信过程都是浏览器自动完成,因此实现CORS通信的关键是服务器,只要服务器实现了CORS接口就可以跨源通信。具体参见阮一峰老师的博客
- 跨文档消息机制:可以通过
window.postMessage
的 JS 接口来和不同源的 DOM 进行通信,当然此功能不仅仅可以用来操作DOM。
浏览器页面安全漏洞
在安全性上做出妥协必然会带来一些漏洞,这里介绍XSS和CSRF两种
XSS 跨站脚本攻击
全称Cross Site Scripting,指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。恶意脚本可以做以下事情:
- 通过
document.cookie
窃取cookie - 监听键盘事件等用户行为,比如用户输入信用卡密码
- 修改DOM伪造登录窗口,骗取用户名和密码
- 生成广告弹窗
攻击方式
恶意脚本注入的方式 通常有存储型、反射型和基于 DOM 三种。
- 存储型:黑客利用站点漏洞将恶意脚本存储在站点里,用户访问该站点就有可能请求并执行此恶意脚本,从而将某些信息发送给恶意服务器。比如一个站点没做好过滤,黑客可以将用户名设置为一段脚本,其他用户页面出现黑客用户名时,就会被攻击。
- 反射型:恶意 JS 脚本属于用户发送给网站请求中的一部分,随后网站又把恶意 JavaScript 脚本返回给用户。当恶意 JavaScript 脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。在现实中,黑客经常会通过 QQ 群或者邮件等渠道诱导用户去点击这些恶意链接。比如点击
http://xxxxx/?xss=<script>alert('你被xss攻击了')</script>
,服务器将这段脚本反射到打开的页面中。
Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是反射型和存储型 XSS 攻击不同的地方。
- 基于DOM:不牵涉到服务器,在资源传输过程或者在用户使用页面的过程中修改页面的数据。劫持类型很多,比如通过路由器或本地恶意软件来劫持,在页面传输过程中修改 HTML 页面的内容。
如何防范
- 服务器对输入脚本进行过滤或转码:针对存储型和反射型攻击,过滤或转码敏感内容,比如
<script>alert('你被xss攻击了')</script>
可以把某些字符转码,使其成为不能被解析的标签。 - 使用 Cookie 的 HttpOnly 属性:很多XSS攻击都是盗取 Cookie,服务器可以为某些 Cookie 设置 HttpOnly 标志,该标志说明此 Cookie 只能使用在 HTTP 请求过程中,所以无法通过 JS 来读取这段 Cookie。
- 使用CSP:内容安全策略,控制浏览器可以为用户加载哪些资源,限制加载其他域下的资源文件,这样即使黑客插入了一个 JS 文件,这个文件也是无法被加载的。也可以禁止向第三方域提交数据、禁止执行内联脚本和未授权的脚本,还提供了上报机制,可以帮助我们尽快发现有哪些 XSS 攻击。具体可见MDN,两种用法:
- 服务器返回
Content-Security-Policy
响应头 <meta>
标签配置
- 服务器返回
CSRF 跨站请求伪造
全称Cross-site request forgery,指黑客诱导受害者进入第三方网站,在第三方网站中,向信任网站发送跨站请求。利用受害者在信任网站已经获取的注册(登录)凭证,绕过后台的用户验证,达到冒充用户对信任网站执行某项操作的目的。
攻击方式
CSRF攻击本身无法窃取到用户Cookie等内容,而是偷用这些信息给受害站点服务器发请求,使服务器误以为是正常请求。当用户打开了黑客的页面后,黑客通常有三种方式去实施 CSRF 攻击:
- 自动发起GET请求:比如黑客的页面有个图片src是一段盗取信息的url,用户进入恶意页面就会被攻击。
- 自动发起POST请求:和上面类似,黑客页面如果有个自动提交的form
- 引诱客户点击链接:黑客设置一个恶意的链接引诱用户点击,恶意链接可能是转账链接等。
和 XSS 不同的是,CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。
需要说明一点,为什么同源策略不能阻止第三方页面获取本站点cookie呢?
答:同源策略并没有完全限制网站不能使用非同源的资源,比如引用第三方script文件等,同样的也没限制一些跨域写操作,比如表单提交。因此只靠同源策略不能阻止CSRF。换句话说,如果可以在第三方站点成功发送跨域请求,或者是发送一些不受跨域限制的请求(表单提交、script请求),只要请求能正常发送,浏览器会自动带上请求的那个站点的cookie。
如何防范
发起CSRF攻击需要有三个必要条件:目标站点有CSRF漏洞、用户登录过用户站点并且保持登录状态、需要用户打开恶意站点。
- 使用 Cookie 的 SameSite 属性:通常 CSRF 攻击都是从第三方站点发起的,属性设置为 Strict 或 Lax 可以做到从第三方站点发送请求时禁止 Cookie 的发送。详情可见MDN
- 加入跨域限制: 验证请求站点的来源,HTTP 请求头中可以有 Referer 和 Origin 属性,记录了该 HTTP 请求的来源地址,区别是 Referer 有存着详细路径,Origin 只有域名不包含路径。服务器根据这点来阻止攻击。
- CSRF Token:既然恶意站点可以偷用站点Cookie,那可以使用Token来保证安全,用户打开页面以后服务器生成Token传给页面,不把Token存到Cookie中(可以存到localStorage中),请求时带上Token,不存到Cookie中,恶意网站当然就不能偷用到Token了。或者可以使用JWT,具体见阮一峰老师博客。
系统安全
浏览器为了系统安全,引入了安全沙箱来限制渲染进程。
试想,如果没有安全沙箱来限制渲染进程,一段恶意脚本就可能利用浏览器系统漏洞,对浏览器主进程进行攻击,就可以读取和修改浏览器进程内部的任意内容,甚至是穿透浏览器,在用户的操作系统上安装恶意软件、监听用户键盘输入信息以及读取用户硬盘上的文件内容。
浏览器默认一切网络资源(JS脚本、CSS、HTML、图片等等)都是不安全的,当解析或执行这些资源时,就有可能会出问题,而这些内容都是在渲染进程上进行的,基于此,浏览器在渲染进程外层包了一道墙,这就是安全沙箱。
渲染进程在需要进行读取文件、发起网络请求、读取或写入Cookie等等操作时,会通过IPC向内核通信,由内核来完成并给渲染进程传输它所需要的内容。
网络安全
在HTTP协议上加入SSL/TLS安全协议成为HTTPS协议,使用对称加密传输数据,使用非对称加密传输密钥,并加入数字证书机制。还没有具体学习不做记录。
参考文献
李兵老师《浏览器原理与实践》