如果要了解跨域,首先要了解什么是同源策略,同源策略(Same-origin policy,缩写SOP)在 1995 时被引入 Netscape Navigator 2.02,最初旨在保护对 DOM 的跨域访问。这个网上有很多例子,下面我们看一下维基百科上是怎么说同源策略的。
同源策略是指在Web浏览器中,允许某个网页脚本访问另一个网页的数据,但前提是这两个网页必须有相同的URI、主机名和端口号,一旦两个网站满足上述条件,这两个网站就被认定为具有相同来源。此策略可防止某个网页上的恶意脚本通过该页面的文档对象模型访问另一网页上的敏感数据。
同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。
值得注意的是同源策略仅适用于脚本,这意味着某网站可以通过相应的HTML标签访问不同来源网站上的图像、CSS和动态加载脚本等资源。而跨站请求伪造就是利用同源策略不适用于HTML标签的缺陷。
这里面最重要是如何判断是否同源,就是URI、端口或者IP、端口都必须一致,才是同源。
下面是同源与否的一些例子,http和https之所以不同源,其实还是因为http端口是80,https端口是443。
那如果我违反了同源策略,从一个源需要访问另一个源时,就是跨域(Cross-origin)了。跨域会有很多限制,比如:
- Cookie,LocalStorage,IndexDB 等存储性内容无法读取
- DOM 节点无法访问
- Ajax 请求发出去了,但是响应被浏览器拦截了
跨域浏览器就会报错:
Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been block by CORS, policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我们来看一下为什么要进行这些限制。
2.1 Cookie,LocalStorage,IndexDB的限制
首先对不同源的Cookie,LocalStorage,IndexDB的限制。我们以Cookie为例,一般用户的登录信息会存在Cookie里,如果我们允许不同源的Cookie可以互相访问。假设黑客开发一个诱导用户(比如美女)的A页面,当用户的浏览器同时访问A页面和银行网站B页面时,A页面(诱导页面)就可以读取B页面(银行页面)存储的Cookie,之后黑客就可以拿这个Cookie信息去操作你的银行账户了。
2.2 DOM 节点限制
和上面的限制同样,如果只限制了cookie等存储访问,不限制DOM节点的操作和访问,从一个诱导页面就可以操作正在访问的银行页面。也可以获取用户dom中的信息,比如用户名密码等。
2.3 Ajax请求限制
对ajax的限制主要是为了防止跨站请求伪造(Cross-site request forgery,简称CSRF),这里先说一下什么是CSRF。
假如一家银行用以执行转账操作的URL地址如下: bank.example.com/withdraw?ac…
那么,一个恶意攻击者可以在另一个诱导页面上放置如下代码:《img src="https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman" /》
如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。
这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。
透过例子能够看出,攻击者并不能通过CSRF攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户的浏览器,让其以用户的名义执行操作。
跨域有很多的解决方案,在这里先简单总结一下有哪些,这个系列后面的文章会具体的去介绍。
-
JSONP
-
Cross-Origin Resource sharing(跨域资源共享)
-
nginx反向代理
-
Websocket
-
window.postMessage
-
.document.domain + Iframe
-
window.name + Iframe
-
window.location.hash + Iframe
-
浏览器配置修改