php什么是同源策略,安全 初探同源策略及其安全

今天了解了一些有关浏览器同源策略以及CSRF***之后,觉得挺有意思的,所以特此总结一波,给自己囤一点干货这篇文章主要包含三个大的方面:

1.同源策略是什么及其作用

2.如何绕过同源策略

3.CSEF***及防御

b7d08545701ddc15d6b71daa6d2a03eb.png

同源策略及其安全.png

1.同源策略(same-origin policy):

1.1 什么叫做同源:

同源是针对域名来说的,对于任意的域名,只要他们的协议(HTTP,HTTPS)一致,主机一致,端口号一致,就可以将其认为是同源的。

1.2 那么同源策略的作用是什么?

** 说到作用,那么就不可避免地要提及一下为什么会有这个策略的产生吧**

引用一段阮一峰大神的描述:同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?

很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。

由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

再来一段Wikipedia上的描述:In computing, the same-origin policy is an important concept in the

web application security model. Under the policy, a web browser permits

scripts contained in a first web page to access data in a second web

page, but only if both web pages have the same origin. An origin is

defined as a combination of URI scheme, hostname, and port number.This

policy prevents a malicious script on one page from obtaining access to

sensitive data on another web page through that page's Document Object

Model.

This mechanism bears a particular significance for modern web

applications that extensively depend on HTTP cookies to maintain

authenticated user sessions, as servers act based on the HTTP cookie

information to reveal sensitive information or take state-changing

actions. A strict separation between content provided by unrelated sites

must be maintained on the client-side to prevent the loss of data

confidentiality or integrity.

看了这么多的描述之后,我也来一个自己总结的吧。

我认为同源策略之所以出现,就是为了提高在浏览器上网的安全性。这里的 安全性主要是针对 cookie来说的。因为 cookie 保存着我们每个人的上网信息,甚至包含一些涉及个人重要隐私的信息,而没有同源策略之前,我们的这些信息,也即 cookie很容易被他人利用,去做一些羞羞的事情,所以为了保证我们每个网民能够安全的上网,这个策略就应用而生啦。(在这里,我要对NetScape说一声感谢)

** 那么,回归正题,这个同源策略的具体作用都有哪些呢? **

一旦我们进行非同源的跨站访问,那么为了安全起见,在这个过程中,有一些数据的传输会受到限制。比如:Cookie、LocalStorage 和 IndexDB 无法读取。

DOM无法获得

AJAX请求不能发送

这样一来,虽然看起来我们的安全性被牢牢地掌握在自己手中,但是自己的手脚也多多少少受到了一些限制,什么生意呢?如果在我们自己搞的东西中,真的需要进行跨域访问呢?难道当初NetScape在设计的时候就没考虑到这一点吗?

放心,其实是有办法的。

2.那么都有哪些办法能够绕过同源策略来实现相应的功能呢?对于Cookie的传输:

1.1 如果我们现在有两个网页,它们一级域名一致,只是二级域名不同,那么如果要做到使这两个域名能够实现cookie的共享,只需要将这两个页面的 document.domain设置为一级域名即可。

比如 页面一 http://xiao.haha.com/a.html 页面二 http://qian.haha.com/b.html 那么只需要将 document.domain = haha.com即可

1.2 对于两个毫无关系的页面,如果要进行cookie的传输,那么需要借助标签    

对于DOM的传输:

2.1 片段识别符(fragment identifier)

2.2 window.name

2.3 跨文档通信API(Cross-document messaging)

3.对于AJAX请求:

3.1 利用JSONP通信标准

其基本思想是既然AJAX已经被废掉了,那么就换一种还可以继续请求的办法。于是就想到了可以利用

示例代码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);

};

上面代码通过动态添加

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。foo({  "ip": "8.8.8.8"});

由于

3.2 利用WebSocket协议

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

示例如下:GET /chat HTTP/1.1Host: server.example.com

Upgrade: websocket

Connection: Upgrade

Origin: http://example.com/

在上边的示例中,最后一个属性 origin 是重点。该字段表示请求的请求源,然后浏览器根据该地址,判断是否处在白名单中,如果处在,则可以进行本次通信,反之不可。

3.3 利用CORS(跨源资源分享)标准

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。请求方法是以下三种方法之一:

1.HEAD

2.GET

3.POST

HTTP的头信息不超出以下几种字段:

1.Accept

2.Accept-Language

3.Content-Language

4.Last-Event-ID

5.Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

** 对于简单请求: **

浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

** 对于非简单请求: **

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

** 注: CORS协议支持所有的HTTP请求,而JSONP只支持GET请求,所以在这一点上,CORS协议要强大的多。 **

3.CSRF***又是啥子武器呢?

3.1 什么是CSRF***?

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

3.2 CSRF***的原理?

利用cookie,盗用身份从而进行邪恶活动。

具体的作案手段都有哪些呢?

示例1:

银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危险网站B,它里面有一段HTML的代码如下,便会成功。

** 由于同源策略对img标签没有限制,所以向在img标签中的src地址发起请求时,会直接将用户的cookie传递过去,从而盗取用户身份进行非法操作。 **

示例2:

为了杜绝上面的问题,银行决定改用POST请求完成转账操作。

银行网站A的WEB表单如下:

    

ToBankId: 

    

Money: 

    

  

后台处理页面Transfer.php如下:<?php    session_start();

if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))

{

buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);

}

?>

危险网站B,仍然只是包含那句HTML代码,同样也会成功。

**

为什么这次还可以呢,这个锅就得PHP背了,PHP在后端用的是$_REQUEST来获取参数,那么它既可获取GET参数,也可以得到POST。所以在这里,依然用的是GET请求方式了,

同样地在JAVA中, request对象也是如此,不能区分GET和POST**

示例3:

经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:<?php    session_start();

if (isset($_POST['toBankId'] && isset($_POST['money']))

{

buy_stocks($_POST['toBankId'], $_POST['money']);

}

?>

然而,危险网站B与时俱进,它改了一下代码,照样得手:

        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值