Cross-origin 跨域请求
source link: https://segmentfault.com/a/1190000041398310
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Cookie
1993 迎来了
img
标签,这是web
第一次迎来了资源加载<img src="foo.jpg" /> <img src="http://somewhere.com/foo.jpg" />
Set-Cookie: foo=bar
<img src="http://somewhere.com/foo.jpg" /> <script src="http://somewhere.com/foo.js" ></script> <iframe src="http://somewhere.com/foo.html" />
起初这样的设计会导致严重的问题:无论是网站,只要包含上面的标签都会携带 cookie 访问。
更不用说这样的请求了。
<form action="http://somewhere.com./submit"></form>
因此 http
通过 Origin
这个头来限制访问
// XMLHttpRequest 的前身 new ActiveXObject('Microsoft.XMLHTTP');
var req = new XMLHttpRequest() req.addEventListener('load', loadListener); req.open('GET', 'https://example.com/data.txt'); req.send();
const res = await fetch('http://example.com/data.txt', { credentials: 'include', });
现在我们已经使用这样方式请求,但是同样也要受限于服务器是否响应 (下面就是服务器为什么有的会响应)。
跨域资源共享(CORS)
我们通过 access-control-allow-origin
来决定那些那资源可以被跨域访问,例如设置 access-control-allow-origin: *
允许所有资源可以被访问 。并且通过设置 credential
来决定是否携带 cookie
。
access-control-allow-credentials: true
决定是否允许你访问 cookie
。但是同时你必须明确通过 access-control-allow-origin
指出跨域访问的网址。
这些头信息已经在我们通过浏览器发出的请求中设置好了,我们不需要特别关心。例如我们通过 <form>
发送时请求时, Content-Type
已经设置成例如 x-www-form-urlencoded
。
一个小知识点:你可以发送设置成
Content-type: text/plain
的POST
请求。例如通过<form>
来发送x-www-form-urlencoded
的空行间隔。
Referrer
从一个网站跳到另外一个网站时,会有这个头信息
Origin
Referrer
不可靠,所以有了 Origin
这个头信息。Origin
会出现在跨域的请求中。
通常来说,我们限制了 access-control-allow-origin
网站就已经足够安全。
除了
CORS
得GET
请求外,其他的GET
请求都不带Origin
。可以通过判断Origin
得知这个是不是跨域的请求。
跨域中危险的 cookie
当我们不带 cookie
发出请求时,可能会引发很多问题。首先我们要知道什么情况 access-control-allow-origin: *
时是安全的 ,例如家中分布的IoT
设备,本地的请求。除此之外都可能引发CSRF
攻击。
限制 cookie
例如通过图片追踪。当你访问 other.com
时,<img />
会允许设置cookie
从而进行跟踪。
<!-- site: other.com --> <img src="http://statics.com/user-avatar-a.png" />
设置 SameSite: Strict | Lax | None
。Lax
不允许 img
、 iframe
、 AJAX
、 POST
表单携带 cookie
(当前所在地站点是:other.com ) 。不过 Lax
允许<a>
链接,预加载请求,GET
表单这3种情况的携带 cookie
。
Set-cookie: sessionid=1234567; SameSite=Lax; HttpOnly; Max-Age=3153600
SameSite: Strict
这会导致所有的跨域均不带cookie
,例如在非github
的网站上跳转至github
将不会携带cookie
,此时github
将显示未登录。
httponly
:不能通过javasript
获取cookie
跨域资源策略(CORP)
Cross-Origin-Resource-Policy: same-site
标记为 same-site
的资源只能从相同站点加载。
Cross-Origin-Resource-Policy
响应头会指示浏览器阻止对指定资源的无源跨域/跨站点请求。
在下面这个请求中加入 CORP
的头信息,图片将加载失败。
<!-- site: other.com --> <img src="http://statics.com/user-avatar-a.png" />
Cross-Origin-Resource-Policy: same-site | same-origin |cross-origin
下面这个场景是无法通过同一个 cookie
处理,虽然你可以将 cookie
放在 html
的请求中。
<img src="http://example.com/secret.html" />
这个请求仍然会将 html
文件的请求放到进程中,来表示当前请求处理完成。这可能会引起某些问题。Meltdown and Spectre
Cross-Origin-Read-Blocking
阻止跨域的请求动作,同时跨域的返回也会被阻止。例如上面的请求,将不会进入浏览器的处理进程中。
请求在进入进程前,会注意mine type
如果是 nosniff
(nosniff
将阻止浏览器针对 content-type
的一些优化)。Chrome
浏览器针对 html
文件的请求并且不是跨域将会阻止。
CORB
是不头信息
跨域嵌入策略 (COEP)
Cross-Origin-Embedder-Policy: require-corp
文档只能从同一来源加载资源,或者显式被标记为可从另一来源加载的资源。
为了从其他来源加载资源,需要支持跨域资源共享(CORS)
或跨域资源策略(CORP)
。
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Resource-Policy: cross-origin
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK