前端跨域

WEB前端中最常见的两种漏洞,XSS与CSRF,XSS,即跨站脚本攻击、CSRF即跨站请求伪造,这两者都有跨站,站顾名思义就是网站,而把这个概念扩大就是域。两者属于跨域安全攻击

一、 域

域,即域名对应的站点。不同的域名对应的不同的网站,相同的域名不同的端口也对应的不同的网站,因此域,从字面意思以及实际意思在web中代表的是网站

二、同源策略(SOP)

同源策略限制了从同一个源加载的资源如何与另一个源内的资源进行交互,该策略旨在阻止隔离恶意文件交互。具体表现为浏览器只允许请求当前域的资源,而对其他域的资源表示不信任。那怎么才算跨域呢?

  1. 请求协议http,https的不同
  2. domain的不同
  3. 端口port的不同

    三、跨域

跨域就如字面意思一样,跨过不同域之间的限制进行信息交互,其本质就是绕过同源策略的严格限制。究其根本是因为开发功能性与安全性会有一定的矛盾,例如有时候父域名下的不同子域名需要进行信息交互,如果还要进行同源限制,未必就有点不合时宜,所以就产生了一些跨域交流的技术。

四、跨域技术

跨域,从一个域到另一个域将其归为跨域。大致将其归结为两种情况:

1、跨域请求

2、跨域跳转

五、跨域威胁

常见的跨域威胁方面大概可分为JSONp或者Cors这两者

Cors 全称是”跨域资源共享”(Cross-origin resource sharing),具体作用就跟名字一样,主要用于跨域的资源共享信息交互。在了解具体流程时,先了解点前置知识。

  1. 简单请求:

1): 请求方式只能是:headgetpost

2): 请求头允许的字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:application/x-www-form-urlencoded、multipart/form-data、text/plain 三选一

2.复杂请求:不满足上面的都是复杂请求

Cors可以通过在HTTP增加字段来告诉浏览器,哪些不同来源的服务器是有权访问本站资源的,当不同域的请求发生时,就出现了跨域的现象

简单请求:

当我们向一个不同域的网页发起简单请求时,浏览器会先对这个请求进行校对,会对请求头添加一个origin字段(谷歌游览器在非跨域情况下,也会发送origin字段)

图片

(字段里为当前域)

然后服务器对该请求进行检测,若符合要求,就能放行

图片

其中,Access-Control-Allow-Origin标识允许哪个域的请求。如果服务器不通过,根本没有这个字段,接着触发XHRonerror,再接着你就看到浏览器的提示xxx的服务器没有响应Access-Control-Allow-Origin字段

1
2
3
4
//指定允许其他域名访问
'Access-Control-Allow-Origin:http://172.20.0.206'//一般用法(*,指定域,动态设置),3是因为*不允许携带认证头和cookies
//是否允许后续请求携带认证信息(cookies),该值只能是true,否则不返回
'Access-Control-Allow-Credentials:true'

上面说到的Access-Control-Allow-Origin有多种设置方法:

  1. 设置*是最简单粗暴的,但是服务器出于安全考虑,肯定不会这么干,而且,如果是*的话,游览器将不会发送cookies,即使你的XHR设置了withCredentials
  2. 指定域,如上图中的http://172.20.0.206,一般的系统中间都有一个nginx,所以推荐这种
  3. 动态设置为请求域,多人协作时,多个前端对接一个后台
    withCredentials:表示XHR是否接收cookies和发送cookies,也就是说如果该值是false,响应头的Set-Cookie,浏览器也不会理,并且即使有目标站点的cookies,浏览器也不会发送

复杂请求:

最常见的情况,当我们使用putdelete请求时,浏览器会先发送option(预检)请求

预检请求

与简单请求不同的是,option请求多了2个字段:

Access-Control-Request-Method:该次请求的请求方式

Access-Control-Request-Headers:该次请求的自定义请求头字段,服务器检查通过后,做出响应:

1
2
3
4
5
6
7
8
9
10
//指定允许其他域名访问
'Access-Control-Allow-Origin:http://172.20.0.206'//一般用法(*,指定域,动态设置),3是因为*不允许携带认证头和cookies
//是否允许后续请求携带认证信息(cookies),该值只能是true,否则不返回
'Access-Control-Allow-Credentials:true'
//预检结果缓存时间,也就是上面说到的缓存啦
'Access-Control-Max-Age: 1800'
//允许的请求类型
'Access-Control-Allow-Methods:GET,POST,PUT,POST'
//允许的请求头字段
'Access-Control-Allow-Headers:x-requested-with,content-type'

这里有个注意点:Access-Control-Request-MethodAccess-Control-Request-Headers返回的是满足服务器要求的所有请求方式,请求头,不限于该次请求 实际案例:
以一加官网为例

登陆后,访问个人信息,然后利用burpsuite抓包,修改origin的域,发现任意域都可以被服务器接受

图片

构造exp

图片

成功利用

JSONp,全称是(JSON with Padding)。是一种简单的服务器与客户端跨域通信的办法,此种跨域只能发起GET请求。其基本思想是网页通过添加一个script元素,向服务器请求JSON数据,这种做法不受同源策略限制。服务器收到请求后,将数据放在一个指定名字的回调函数里传回来

原理:通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}

window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
1
2
3
4
5
6
7
8
<script src="http://example.com/data.php?callback=dosomething"></script>

<script type="text/javascript">
function dosomething(jsondata){
//处理获得的json数据
}
</script>

jquery用法

1
2
3
4
5
<script type="text/javascript">
$.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){
//处理获得的json数据
};
</script>

JSONP的优缺点
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题

jsonp实现流程

1、服务端必须支持jsonp,且拥有jsonp跨域接口(前提)

2、浏览器客户端声明一个回调函数,其函数名作为参数值,要传递给跨域请求数据的服务器,函数形参为要获取到的返回目标数据

3、创建一个