浏览器为什么选择了如今的同源策略

2022-03-26 17:48:16 +08:00
 wheelg

浏览器会禁止下面的类似操作

a.com中的 js 向b.com/api发送了请求,根据同源策略,这样的跨域请求会向b.com 发送一个 OPTIONS 预检请求,如果服务器返回的 Access-Allow-Origins 中不包含a.com ,那么此次请求会被浏览器拒绝,a.com中的 js 拿不到请求返回的数据。

这样的行为如果发生在本地应用程序例如 postman 中时,是可以拿到正常的请求数据的,因为 postman 没有同源策略,不会限制发送任何请求,那么为什么浏览器要对此做出限制?

网上的大部分解释是,浏览器在向某个域名发起请求时,会携带上对应的网站 cookie ,如果用户登录了b.com,又打开了a.coma.comb.com/api发送的请求会带上b.com的 cookie ,会让b.com服务器认为是用户本人在操作,导致恶意攻击的发生。

那么为什么浏览器不能分辨是哪个网站发起的请求呢?为什么浏览器不能在检测到是a.com发出的请求时,不携带b.com网站保存的 cookie 呢?这样不就能同样规避此类攻击吗?就如同在浏览器直接输入 api 网址那样拿到返回结果不行吗?

我的理解是,浏览器厂商不能这样做,因为许多广告厂商需要在网站中嵌入第三方 cookie ,这样才能通过第三方 cookie 来确定同一用户,方便广告投放,但是这个说法也显然站不住脚,因为如今许多浏览器厂商都在主动禁止第三方 cookie ,那么这个同源策略到底保护的是什么呢?

7441 次点击
所在节点    程序员
72 条回复
HelloAmadeus
2022-03-26 17:53:26 +08:00
先了解一下跨域攻击吧,然后再思考同源策略合理不合理。
wheelg
2022-03-26 17:55:28 +08:00
@HelloAmadeus 我理解的跨域攻击场景就是我说的这种呀,还有其他形式的场景吗?
Biwood
2022-03-26 17:58:50 +08:00
那么为什么浏览器不能分辨是哪个网站发起的请求呢?为什么浏览器不能在检测到是 a.com 发出的请求时,不携带 b.com 网站保存的 cookie 呢
Biwood
2022-03-26 18:01:05 +08:00
手误发出去了,上面那句是引用帖子内容,回答是:浏览器已经有这个机制了,而且这也算是同源策略的一部分。

你说的跨域攻击属于是攻击者已经绕过了上面那个机制的情况
wheelg
2022-03-26 18:07:27 +08:00
@Biwood 有点好奇具体的跨域攻击方式是什么,理论上隔离做得好的话,网页应用应该和本地应用拥有同等的安全性,为什么还要一个额外的限制,仅仅是因为网页打开太方便了吗?
Yechs
2022-03-26 18:29:36 +08:00
postman 是用户控制的, 网页不做的话 a 网站就可以用 b 网站 token 进行操作攻击, 这是不受控的
des
2022-03-26 18:56:46 +08:00
你也不想,好好的吃着火锅看着视频,你另外一个账户里的余额不翼而飞吧?
session 不止可以通过 cookie 来做,现在大把的 header 塞 token 的
nuk
2022-03-26 19:03:23 +08:00
假如一个 ups 有个 api ,可以通过网络来让它重启 http://192.168.1.1/reboot
那如果别人知道你家的 ups 地址,直接嵌入 img src=http://192.168.1.1/reboot 是不是每次一访问就重启了,你还找不到原因。
如果没有同源策略,网络上将会有无穷无尽的攻击,因为一般认为内网的设备是安全的,所以很多人不会设置足够的安全策略。
wheelg
2022-03-26 19:05:43 +08:00
@nuk 直接知道地址的话不用网页访问,直接 curl 命令访问也可以攻击呀
wheelg
2022-03-26 19:06:48 +08:00
这里说一下我的理解吧:

如果浏览器能像本地应用程序那样做好沙盒环境,保证一个网站无法读取到另一个网站的本地数据(包括 cookie 、localstorage 等等)的话,对于网站而言,这样的安全性已经足够了。但是网页和本地应用最大的区别是网页打开太方便了,导致用户受到的网络攻击的可能性远远高于本地应用,并且浏览器对自己采取的安全措施十分不放心,正如这个[回答]( https://stackoverflow.com/questions/29167428/same-origin-policy-and-cors-whats-the-point)中说的一样,浏览器的安全措施如果仅仅是刚好够用的话都已经不能满足 W3C 对安全的要求了

`This all shows that the security model of WWW is very subtle and not well thought of. It has evolved instead of being well-designed. `

如果允许网页无限制地访问非同源网站内容,那么浏览器潜在的漏洞导致的安全事故会极大地影响互联网的安全,除去可能存在的隐私泄漏问题,恶意网站还可能会让每一个访问它的用户为它打工,例如静默访问其他网站刷取点击量,或者成为 DDOS 的帮凶,因此 W3C 才选择了现在的这个极为严格的同源策略作为安全手段,就是为了尽可能减少安全问题。
nuk
2022-03-26 19:07:50 +08:00
@wheelg 知道地址就做个假的网页让他访问就行,比如用微信发给他
他怎么可能傻的自己用 curl 访问。。
wheelg
2022-03-26 19:09:29 +08:00
@des 如果浏览器能做到足够安全的沙盒环境,把每个网站视作独立的本地应用来看待,不让网站有互相访问本地数据的可能性就可以防止这一点了,类似于 bilibili 客户端和手机银行客户端的关系,而不需要使用现在这个这么严格的同源策略,所以说目前的同源策略目的也不是为了防止这种问题。
wheelg
2022-03-26 19:15:08 +08:00
@nuk 嗯,所以我觉得,同源策略最主要的目的不是保护网站自己,而是保护其他服务器不被网站攻击,就好像你也可以发给他一条 curl 命令骗他输到终端里一样,但是打开网页比起打开终端或者其他应用来说要方便多了,所以才会用同源策略来禁止网站的能力
rekulas
2022-03-26 19:56:07 +08:00
@nuk 你举这个例子似乎不合适,同源策略在这种情况似乎不生效
如果你的 api 是 get ,那同源限制无效
如果你的 api 是 post ,即使没有同源策略也不会出问题
noe132
2022-03-26 20:04:52 +08:00
很多问题不能光从技术角度分析,这个问题的根本原因是之前没有同源策略这一套,然后后来加上的这么一套规则。如果规则太严格,很多老应用就直接不能用了。如果让重新设计一套 web 安全系统,而不考虑兼容性,当然你说的方案比现在的强多了
hazardous
2022-03-26 20:15:24 +08:00
上面好多人没懂 OP 的意思,人家并不是问为什么要有同源策略,而是问为什么采用了这一种实现方式,而不是另一种。
musi
2022-03-26 20:29:01 +08:00
onice
2022-03-26 20:40:49 +08:00
同源策略是为了安全考虑,是浏览器的安全机制。假如没有同源策略,你访问任何站点,站点能获取你浏览器中其他站点的 cookie ,那还安全吗?

比如我构造一个恶意站点,使用 JS 读你邮箱站点的 cookie ,并保存。只要你的 cookie 有效,我就可以通过你的 cookie 登录你的邮箱。
hazardous
2022-03-26 20:42:08 +08:00
我觉得站在 b.com 网站的角度上说,是为了保护 b.com 网站的资源不会被被其它网站随意使用,只有你白名单里的网站,也就是 access-allow-origin 的网站能调用你的接口或者访问你的资源。
hazardous
2022-03-26 20:46:20 +08:00
我这种情况没有涉及到 cookie 的问题,所以 OP 的修改的方案无法实现我这种需求。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/843069

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX