为何浏览器要阻止不带 cookie 的跨域请求的响应?
在 Google 页面执行:
xhr=new XMLHttpRequest
xhr.addEventListener('load',()=>console.log('xhr load'))
xhr.open("GET","https://www.baidu.com")
xhr.withCredentials = false; // 不发送 cookie
xhr.send(null)
响应依然被浏览器阻止:
XMLHttpRequest cannot load https://www.baidu.com/.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://www.google.com' is therefore not allowed access.
但是 IE8 里的 XDomainRequest
不发送 cookie,也不会阻止。
想访问一些网站的公开 API,可是这些网站的响应又不带 Access-Control-Allow-Origin,只能用 JSONP,有些不爽。
所以我想问为何浏览器要阻止不带 cookie 的跨域 XHR 请求的响应?有什么安全方面的风险?
1
oh 2017-07-24 22:41:31 +08:00
一般真正公开使用的 API 都是带 Access-Control-Allow-Origin 的,如果确实不带可以用后端反代理一下解决 jsonp 的问题。
|
2
580a388da131 2017-07-24 23:31:15 +08:00
同源策略
|
3
ferrum 2017-07-25 00:07:54 +08:00 via iPhone
跨域请求,服务器没有返回指定 header (通过 options 请求得知),浏览器就会阻止,和你设不设置 withCredentials 没有关系。
|
4
1OF7G OP @ferrum #3 我知道浏览器的这种行为,也明白允许带 cookie 发送跨域请求的风险。只是不明白不带 cookie 时候有和风险,为何浏览器也不允许?
|
5
wbswjc 2017-07-25 02:49:19 +08:00
防止跨站攻击和有没有 Cookie 没关系吧,反正就是不能让脚本在用户不知情情况下随意进行跨域请求就是了
|
6
wwqgtxx 2017-07-25 06:38:26 +08:00 via iPhone
建议你去 mdn 好好看看 cors 的文档,那里详细的写了什么情况下可以正常的发送跨域请求,你的测试过于单一了
|
7
janxin 2017-07-25 07:15:14 +08:00 via iPhone
有
|
8
lcorange 2017-07-25 07:29:06 +08:00 via Android
当然有风险,比如你可以在自己网站上模拟 v 站登录,不用发 cookie,但对用户来说是危险操作
|
10
t6attack 2017-07-25 07:40:27 +08:00 5
访客问一个页面,该页面可以自由对它域进行操作。会导致什么后果?
可以在访客不知情的情况下,对其他网站进行注册机式攻击、垃圾信息轰炸。可以给其他网站页面刷点击量,给某个视频刷攒。刷某个关键词刷搜索量。。甚至可以 保持长连接 /定时循环请求,让在线访客 随时等候服务端指令,收到指令后,在线用户集体对外域执行各种操作。。 可以这么说:如果允许跨域,从一定程度来讲,访客就成肉鸡了。 |
11
t6attack 2017-07-25 07:54:51 +08:00 1
纠正一下,不是一定程度。如果允许跨域,访客就是肉鸡。
可以直接实现一个访客代理了,每个访客都可以变成一个代理 IP 资源。服务端爬虫受到 IP 限制是吧?那我利用用访客端发送请求。 只要你的网站有一个外国访客在线,那么你可以直接利用这个外国访客进行 科学上网 了。 只要允许跨域,这一切都可以在用户不知情的情况下实现。 |
12
torbrowserbridge 2017-07-25 07:59:06 +08:00 2
一群人答非所问
|
13
qinxi 2017-07-25 08:50:37 +08:00
@torbrowserbridge 就等你一个回答,不然这句话同样送给你
|
14
gaolycn 2017-07-25 08:57:21 +08:00 via Android
|
15
gaolycn 2017-07-25 08:59:13 +08:00 via Android
楼主的意思是为什么这么限制,不这样会有什么风险
|
16
oott123 2017-07-25 09:14:10 +08:00 via Android
我认为最大的风险不在于你可以发送请求,而在于你可以获取它的返回内容。
发送请求本身有很多方法可以做到,但取返回内容没有。 考虑到真实世界里很多内容并不一定通过 cookies 鉴权,而是比如 ip 之类的鉴权,这类请求是不安全的。 再比如楼上几位说的,若有这种特性,极有可能被用作前端爬虫之类的行为。 |
17
jugelizi 2017-07-25 09:48:30 +08:00
纠正一下
跨域并非没有发送,实际上请求已经到对方服务器 只是返回的响应经过浏览器判断给拦截了而已 |
18
flowfire 2017-07-25 09:52:13 +08:00
同 LS 跨域请求已经送达对方服务器
只是假如服务器没有明确指出 “允许跨域” ,浏览器是不会让页面上的脚本获取到返回值的 [甚至连 “对方服务器不允许跨域” 这种信息都无法从脚本中获取到] |