程序员应对浏览器同源策略的姿势

简介: 浏览器最基本的安全规范——同源策略(Same-Origin Policy)。所谓同源是指域名、协议、端口相同。不同源的浏览器脚本(javascript、ActionScript、canvas)在没明确授权的情况下,不能读写对方的资源。

同源策略


浏览器最基本的安全规范——同源策略(Same-Origin Policy)。所谓同源是指域名、协议、端口相同。不同源的浏览器脚本(javascript、ActionScript、canvas)在没明确授权的情况下,不能读写对方的资源


同源策略规定了浏览器脚本互操作web数据的基本原则,若没有这一基本原则,那么:


  1. 某域下DOM元素被另一方任意操作、篡改,导致页面显示失控


  1. 某域下的cookie等与该域相关的数据片段可以随意读取,导致与该域密切相关的浏览器cookie片段可能失真


  1. 恶意网站能随意执行Ajax脚本偷取隐私数据,导致该域下核心业务数据被抓取.


同源策略在实施中面临的问题


默认的同源策略 限制了脚本互操作其他域的能力,大棒一挥, 关闭了A站脚本正常访问B站数据的需求。有以下变通方法:


  1. 实现CORS (Cross-Origin Resource Sharing)


  1. 使用JSONP (JSON Padding)


  1. 建立一个本地代理服务器,这样先同源访问,由代理服务器转发请求


方案1:CORS是w3C对于跨域请求推出的明确方案;方案2、3均是Hack行为。


CORS跨域请求方案


W3C推出的跨域请求方案:让web服务器明确授权非同源页面脚本来访问自身,以Response特定标头Access-Control-*******-体现;目前现代浏览器均认可并支持这些标头


CORS特定HTTP标头,为浏览器提供了授权脚本跨域访问其他域名页面数据的通道。


常规的带Cookie Ajax跨域请求


const invocation = new XMLHttpRequest();const url = 'http://bar.other/resources/credentialed-content/';function callOtherDomain(){  if(invocation) {    invocation.open('GET', url, true);    invocation.withCredentials = true;   // Ajax请求默认不会发送凭据, 这里设定在Ajax跨域请求中发送凭据    invocation.onreadystatechange = handler;    invocation.send();   }}


d35e17fba6e5b1ec4b625e744f34d34f.png


CORS规范


  1. 浏览器发起CORS或POST请求,浏览器会自动携带Origin标头(指示请求来自于哪个站点)


  1. Web服务器实现跨域访问授权逻辑, 授权结果在Response中以Access-Control--******* 标头体现


最常见的Access-Control-Allow-Origin标头包含  * / Origin /null三种响应值;当请求是携带凭据的跨域请求,不可囫囵吞枣地指定为*通配符,而必须指定特定Origin


  1. 浏览器会遵守Access-Control--*******-- 标头值所施加的跨域限制


    GET /resources/access-control-with-credentials/ HTTP/1.1Host: bar.otherUser-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3preAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Connection: keep-aliveReferer: http://foo.example/examples/credential.htmlOrigin: http://foo.exampleCookie: pageAccess=2
    HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:34:52 GMTServer: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2X-Powered-By: PHP/5.2.6Access-Control-Allow-Origin: http://foo.exampleAccess-Control-Allow-Credentials: trueCache-Control: no-cachePragma: no-cacheSet-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMTVary: Accept-Encoding, OriginContent-Encoding: gzipContent-Length: 106Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
    [text/plain payload]


    以上表示了一个常见的携带cookie跨域Ajax Get请求,其中Access-Control-Allow-Credentials: true指示浏览器可以将跨域请求的Response结果暴露给页面。


    预检Preflight


    对于非简单Ajax请求(通常是GET以外的HTTP方法,或者某些MIME类型的POST用法),CORS规范要求发起"预检"请求。



    不过,预检请求不需要你手动发起,浏览器会自动使用OPTIONS请求方法从服务器请求支持的方法,然后在服务器“批准”时,使用实际的HTTP请求方法发送实际请求。

    下图显示 浏览器判断 非简单请求的逻辑图:


    dfb06b416a9648b43bf3a0d1d5472a74.jpg


    下面使用POST动作发起Ajax跨域请求,同时自定义request header:X-PINGOTHER,该请求触发浏览器预检行为


      const invocation = new XMLHttpRequest();const url = 'http://bar.other/resources/post-here/';const body = '<?xml version="1.0"?><person><name>Arun</name></person>';    function callOtherDomain(){  if(invocation)    {      invocation.open('POST', url, true);      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');      invocation.setRequestHeader('Content-Type', 'application/xml');      invocation.onreadystatechange = handler;      invocation.send(body);     }}



      e769913c9a6ca36529c5b740bd125bba.png


      程序员调试CORS的苦恼


      跨域请求发生在A--->B 两站,作为某一方开发人员,调试CORS相对麻烦


      67fb5478757f0ad1fcb26b5bb32db08a.png


      经过本StackOverFow工程师的检索,curl 工具可优雅高效模仿Ajax跨域请求:


        #  http://example.com 向谷歌站点发起一个跨域Get请求curl -H "Origin: http://example.com" --verbose \ https://www.googleapis.com/discovery/v1/apis?fields=


        从浏览器Network,将请求以cUrl格式拷贝出来,改改。


        5f0fee4ae67c031e87e791a9a084496b.jpg


        总结


        1. 浏览器同源策略限制对象是浏览器脚本


        1. 存在跨域请求的场景,某些方案是Hack行为;


        1. W3C推出的CORS 是标准的跨域请求方案,思路是在服务端Response标头体现 授权, 浏览器遵守该授权标头。


        1. 对于非简单的脚本跨域请求,浏览器会自动发起 Option请求预检, 大部分时候无需关注


        1. 提供curl 工具帮助高效、优雅调试CORS。


        后续会聊聊浏览器的另一个有用的安全策略:Cookie SameSite策略,尽请关注.

        相关文章
        |
        19天前
        |
        存储 安全 JavaScript
        浏览器的同源策略
        【10月更文挑战第31天】浏览器的同源策略是浏览器安全模型的重要组成部分,它通过限制不同源之间的资源交互,有效地保护了用户和网站的安全。开发者在进行Web开发时,需要充分理解和遵循同源策略,同时合理地运用各种跨域技术来满足业务需求,确保网站的安全性和功能性的平衡。
        38 2
        |
        5月前
        |
        安全 前端开发 JavaScript
        CORS是W3C标准,解决浏览器同源策略限制的跨域数据访问。
        【6月更文挑战第27天】CORS是W3C标准,解决浏览器同源策略限制的跨域数据访问。它通过服务器在HTTP响应头添加`Access-Control-Allow-*`字段允许特定源请求。简单请求无需预检,非简单请求会发OPTIONS预检请求。服务器配置CORS策略,客户端正常请求,浏览器自动处理。若未正确配置,浏览器将阻止响应,保障安全。
        63 0
        |
        6月前
        |
        JavaScript 前端开发 安全
        JavaScript DOM 操作:解释一下浏览器的同源策略。
        **同源策略**是浏览器安全基石,它阻止脚本跨不同协议、域名或端口访问资源,防止恶意行为。例如,HTTP页面无法直接用JS获取HTTPS页面内容。**CORS**允许跨域请求,但需服务器配合设置,通过`document.domain`属性可配置,但仍受限于服务器配置。
        53 4
        |
        6月前
        |
        前端开发 JavaScript 程序员
        推荐给前端程序员的5款浏览器插件
        推荐给前端程序员的5款浏览器插件
        116 0
        |
        6月前
        |
        JavaScript 前端开发 Go
        浏览器中的同源策略
        【1月更文挑战第2天】
        |
        JavaScript 安全 前端开发
        浏览器基础原理-安全: 同源策略
        浏览器基础原理-安全: 同源策略
        66 0
        |
        JSON 前端开发 JavaScript
        什么是浏览器同源策略?如何处理同源策略带来的跨域问题?
        什么是浏览器同源策略?如何处理同源策略带来的跨域问题?
        211 0
        |
        存储 JSON 安全
        浏览器安全之同源策略
        浏览器-安全策略
        113 0
        |
        Web App开发 数据采集 JavaScript
        剑走偏锋,正经程序员都在用的无头浏览器到底有多神奇?
        浏览器是再熟悉不过的东西了,几乎每个人用过,比如 Chrome、FireFox、Safari,尤其是我们程序员,可谓开发最强辅助,摸鱼最好的伴侣。 浏览器能干的事儿,无头浏览器都能干,而且很多时候比标准浏览器还要更好 用,而且能实现一些很好玩儿的功能,我们能借助无头浏览器比肩标准浏览器强大的功能,而且又能灵活的用程序控制的特性,做出一些很有意思的产品功能来,稍后我们细说。
        |
        前端开发 Python
        Python 使用CORS跨域资源共享解决flask服务器跨域问题、浏览器同源策略
        Python 使用CORS跨域资源共享解决flask服务器跨域问题、浏览器同源策略
        486 0

        热门文章

        最新文章

        下一篇
        无影云桌面