跨域问题

 

傻傻分不清之 Cookie、Session、Token、JWT

一、产生原因

浏览器的同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

说简单点,同源策略就是浏览器本身的一种特殊属性,浏览器在访问资源时会在同源策略约束下,避免不同的站点相互之间轻易的获取信息。

所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开百度和谷歌的页面。浏览器的百度tab页执行脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

举个例子:比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),
如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
何谓同源:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示它们同源。
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,而不受同源限制,

但浏览器会限制脚本中发起的跨域请求。比如,使用 XMLHttpRequest 对象和Fetch发起 HTTP 请求就必须遵守同源策略。
Web 应用程序通过 XMLHttpRequest 对象或Fetch能且只能向同域名的资源发起 HTTP 请求,而不能向任何其它域名发起请求。
不允许跨域访问并非是浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
最好的例子是CSRF跨站攻击原理,请求是发送到了后端服务器,无论是否设置允许跨域,


有些浏览器不允许从HTTPS跨域访问HTTP比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是特例。

二、跨域问题的解决方法

1、通过jsonp跨域

  • JSONP是一个非官方协议,它允许在服务器端集成script tags返回至客户端,通过javascript callback的形式实现跨域访问。
  • 基本思想:网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源策略限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
    <script type="text/javascript">
        function jsonpCallback(result){
            //alert(result);
            for(var i in result){
                alert(i + ":" + result[i]);     //循环输出
            }
        }
        var JSONP = document.createElement("script");
        JSONP.type = "text/javascript";
        JSONP.src = "http://crossdomain.com/services.php?callback=jsonpCallback";
        document.getElementsByTagName("head")[0].appendChild(JSONP);
    </script>

2、通过修改document.domain来跨子域

 

3、使用window.name来进行跨域

window.name+iframe需要目标服务器响应window.name,window对象有一个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window. name都有读写的权利,window.name 是持久存在一个窗口载入过的所有页面中的!

4、使用HTML5中新引进的window.postMessage方法来跨域传送数据

  • HTML5引入了一个全新的API:跨文档消息传输Cross Document Messaging 。它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用)
  • web sockets原理:在JS创建了web sockets之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockets协议。
  • otherWindow.postMessage(message, targetOrigin)
    otherWindow:指目标窗口,也就是给哪个窗口发消息,是window.frames属性的成员或者由window.open方法创建的窗口。
    参数说明:
    (1)message:是要发送的消息,类型为string,object
    (2)targetOrigin:是限定消息接收范围,不限制使用“ * ”

5、使用代理服务器,使用代理方式跨域更加直接,因为同源限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了

三、CSRF 攻击原理及防护

CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,也被称为 one-click attack 或者 session riding。 

攻击原理 :CSRF攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。

图解:

    CSRF攻击的原理:

        ①用户正常登录A银行网站,

        ②A网站返回cookie信息给用户,浏览器保存cookie信息

        ③在A网站没有退出登录的情况下(或者说cookie信息没过期), 登录了恶意网站B

        ④恶意网站B,提前准备好转账表单或者其它请求 ,将其隐藏. 把提交到A网站的按钮设置为一个"领取优惠券"的图片链接.用户 点击链接

        ⑤在用户主观未知的情况下,访问A网站,此时浏览器会自动携带cookie信息

        ⑥A网站识别到cookie信息,默认为是用户本人做出的请求,根据请求做出相应的操作.

        ⑦用户收到损失.

 

CSRF攻击防护:

1、API 仅接受json

2、验证HTTP Referer字段

3、在请求地址中添加token验证

  • 在 HTTP 请求中以參数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。
  • token须要足够随机
  • 敏感的操作应该使用POST。而不是GET,以form表单的形式提交。能够避免token泄露。

  在请求参数中加入一个混淆字符串csrf_token.

        简单来说,服务器在接受到请求后, 返回给用户两个csrf_token值, 一个放在cookie信息中,浏览器会保存,下次请求的时候浏览器自动携带.  一个放在前端页面中(例如:表单域或者ajax的请求头中), 当用户再次向服务器发送数据的时候,  服务器会对比cookie中和前端页面中的csrf_token值,如果一样,证明是用户操作,如果不一样,证明是非法操作.

  恶意网站B因为页面是提前写好的,无法获取到csrf_token值(cookie同源策略),所以服务器接受到请求的时候,会显示非法操作,从而保证了用户个人信息的安全.解决了csrf攻击

4、提交验证码
在表单中添加一个随机的数字或字母验证码。通过强制用户和应用进行交互。来有效地遏制CSRF攻击。

参考:

https://blog.csdn.net/diu_brother/article/details/88367029

https://www.cnblogs.com/wangpenghui522/p/6284355.html

https://www.cnblogs.com/well-666/p/12185098.html

https://blog.csdn.net/qq_42327755/article/details/80575565

https://www.jianshu.com/p/451e575a3a8a

原文地址:https://www.cnblogs.com/developer-qin/p/13447622.html