浏览器页面的保护机制--同源策略
同源策略指的是我们访问站点的:协议
、域名
、`端口号 一致才叫同源,有一个不一样,都会被认为是跨源(跨域)。
浏览器默认同源站点之间是可以互相访问资源和操作 DOM 的,而不同元源之间想要互相访问资源或者操作 DOM 的话,就需要添加一些安全策略的限制。如下:
DOM 层面:不同源站点之间不能互相访问和操作 DOM。
数据层面:不能获取不同源站点的 Cookie、LocalStorage、indexDB 等数据。
网络层面:不能通过 XMLHttpRequest 向不同源站点发送请求。(后来基于 CORS 可以实现但是也会存在一定的限制)
当然,同源策略也不是绝对隔离不同源的站点,比如 link、img、script 标签都没有跨域限制,这也导致了一些安全问题。如 XSS 攻击和 CSRF 攻击
XSS(跨站脚本攻击)
XSS 叫跨站脚本攻击,原本应该叫 CSS,但是为了和层叠样式区别开,叫 XSS。XSS 攻击是一种代码注入攻击,通过恶意注入 JS 脚本在浏览器运行,然后调取用户信息。
造成 XSS 攻击本质上还是因为网站没有过滤恶意代码。当恶意代码混入正常代码中一起执行时,浏览器没有办法分辨哪些是可信的,然后导致恶意代码也被执行。引起的危害有:
页面数据或用户信息被窃取。如 Cookie、LocalStorage、DOM 等。
修改 DOM。比如伪造登陆窗口或在页面生成浮窗广告。
监听用户行为。如添加 addEventListener 来监听键盘事件,获取用户密码。
流量被劫持向其他网站。用户刚进入一个网站,就直接跳转到另外一个网站上。
XSS 攻击有三种类型:存储型、反射型、DOM 型。
存储型
存储型 XSS 攻击主要是将恶意脚本存储到服务端,当读取到该恶意脚本时,浏览器就会识别为一段 JS 代码来执行。比如在评论区,有人写了一段恶意脚本并提交,恶意脚本就会被服务器存储到数据库。当别人访问时,加载这段评论,浏览器就把它识别为 JS 代码来执行。
反射型
通过 URL 参数注入恶意脚本,经服务器解析并响应后,凭借在 HTML 中传回浏览器,然后浏览器解析时就会执行恶意脚本。比如打开包含恶意脚本的链接,打开后会向服务器发送请求,服务器会获取 URL 中的数据然后凭借在 HTML 上返回,然后执行。它和存储型的区别在于不会存储在服务器中。
基于 DOM 型
通过一定的手段在网页向服务端请求资源时,劫持并修改页面的数据,插入恶意代码。
解决方法
- 在服务端对 script 标签进行转义或过滤,再传回给浏览器,这样浏览器在 HTML 解析时就不会把 script 标签当作 JS 代码执行了。
利用 http-only。当 Cookie 设置 http-only 后,会禁止 JavaScript 来访问 Cookie。
- 充分利用 CSP。内容安全策略(CSP)是一个额外的安全层,会限制加载其他域下的资源文件、禁止向第三方提交数据。
CSRF(跨站请求伪造)
CSRF 是跨站请求伪造攻击,顾名思义,就是第三方利用用户的登录信息伪造成用户发起跨域请求。比如邮箱里的乱七八糟链接,打开链接的时候邮箱处于登陆状态,第三方就可以利用这个登陆状态,伪造带有正确 Cookie 的 http 请求,绕过后台验证,冒充用户进行一些操作
发起 CSRF 攻击有三个必要条件
目标网站有 CSRF 漏洞
用户登录过目标网站,并且浏览器保存了登陆状态。
用户主动打开第三方站点。
CSRF 本质上是利用进行 HTTP 同源请求时会携带 Cookie 信息这一特点,实现冒充用户。
解决方法
Cookie Hashing(服务器生成 Cookie 传递给客户端时会生成一个随机数存在其中)。最简单有效方式,因为攻击者理论上无法获取第三方的Cookie,所以伪造 Cookie 失败,无法通过用户验证。
携带 token。客户端向服务器请求 token(令牌),服务器返回 token 给客户端,并且客户端在之后的所有请求中都要带上 token 以作身份验证。
Origin 和 Referer。服务器验证 Referer 是否从第三方网站发出来的,阻止第三方网站请求接口。但是这两者可以通过 ajax 自定义请求头的方式被伪造。