V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wheelg
V2EX  ›  程序员

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

  •  1
     
  •   wheelg · 2022-03-26 17:48:16 +08:00 via iPad · 7742 次点击
    这是一个创建于 1005 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    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 ,那么这个同源策略到底保护的是什么呢?

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

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

    如果浏览器能像本地应用程序那样做好沙盒环境,保证一个网站无法读取到另一个网站的本地数据(包括 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
        11
    nuk  
       2022-03-26 19:07:50 +08:00
    @wheelg 知道地址就做个假的网页让他访问就行,比如用微信发给他
    他怎么可能傻的自己用 curl 访问。。
    wheelg
        12
    wheelg  
    OP
       2022-03-26 19:09:29 +08:00 via iPad
    @des 如果浏览器能做到足够安全的沙盒环境,把每个网站视作独立的本地应用来看待,不让网站有互相访问本地数据的可能性就可以防止这一点了,类似于 bilibili 客户端和手机银行客户端的关系,而不需要使用现在这个这么严格的同源策略,所以说目前的同源策略目的也不是为了防止这种问题。
    wheelg
        13
    wheelg  
    OP
       2022-03-26 19:15:08 +08:00 via iPad
    @nuk 嗯,所以我觉得,同源策略最主要的目的不是保护网站自己,而是保护其他服务器不被网站攻击,就好像你也可以发给他一条 curl 命令骗他输到终端里一样,但是打开网页比起打开终端或者其他应用来说要方便多了,所以才会用同源策略来禁止网站的能力
    rekulas
        14
    rekulas  
       2022-03-26 19:56:07 +08:00   ❤️ 1
    @nuk 你举这个例子似乎不合适,同源策略在这种情况似乎不生效
    如果你的 api 是 get ,那同源限制无效
    如果你的 api 是 post ,即使没有同源策略也不会出问题
    noe132
        15
    noe132  
       2022-03-26 20:04:52 +08:00
    很多问题不能光从技术角度分析,这个问题的根本原因是之前没有同源策略这一套,然后后来加上的这么一套规则。如果规则太严格,很多老应用就直接不能用了。如果让重新设计一套 web 安全系统,而不考虑兼容性,当然你说的方案比现在的强多了
    hazardous
        16
    hazardous  
       2022-03-26 20:15:24 +08:00   ❤️ 1
    上面好多人没懂 OP 的意思,人家并不是问为什么要有同源策略,而是问为什么采用了这一种实现方式,而不是另一种。
    onice
        18
    onice  
       2022-03-26 20:40:49 +08:00
    同源策略是为了安全考虑,是浏览器的安全机制。假如没有同源策略,你访问任何站点,站点能获取你浏览器中其他站点的 cookie ,那还安全吗?

    比如我构造一个恶意站点,使用 JS 读你邮箱站点的 cookie ,并保存。只要你的 cookie 有效,我就可以通过你的 cookie 登录你的邮箱。
    hazardous
        19
    hazardous  
       2022-03-26 20:42:08 +08:00
    我觉得站在 b.com 网站的角度上说,是为了保护 b.com 网站的资源不会被被其它网站随意使用,只有你白名单里的网站,也就是 access-allow-origin 的网站能调用你的接口或者访问你的资源。
    hazardous
        20
    hazardous  
       2022-03-26 20:46:20 +08:00
    我这种情况没有涉及到 cookie 的问题,所以 OP 的修改的方案无法实现我这种需求。
    musi
        21
    musi  
       2022-03-26 20:46:28 +08:00   ❤️ 1
    @rekulas #14 你对同源策略似乎有误解,同源策略分为两部分,一部分是发送,一部分是接受。像 get 这类是简单请求,只限制了接受,并没有限制发送,但是这不是说同源策略就不生效。假如服务器用 get 去做了什么转账之类的操作,那服务器收到请求后该怎么执行怎么执行。至于为什么会对 get 的发送进行放行,rfc2616 中定义 get 操作是安全的。
    thinkershare
        22
    thinkershare  
       2022-03-26 20:53:40 +08:00
    @hazardous 这的确是一个重要考量, 简单资源的盗链目前就在不能修改源的情况下只能使用 iframe, 另外 OP 说的为什么浏览器不能判断是你随意引用别人的内容, 别人也很容易攻击你, 信任是双方的! 我引用的第三方内容在被动态加载到本地化, 在未来完全可能通过修改 DOM, 然后诱导用户输入保密信息, 然后将信息提交到一个第三方从而欺骗你的网站用户, 让网站用户以为是 A 网站自身的行为,. 网页浏览器的普通用户并没有那么高的判断能力!
    musi
        23
    musi  
       2022-03-26 21:21:27 +08:00   ❤️ 1
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E9%A2%84%E6%A3%80%E8%AF%B7%E6%B1%82

    和上面两篇结合起来看效果更佳。
    这里做下总结:浏览器不能直接禁止 a 网站在访问 b 网站时去掉 b 网站的所有会话信息,因为这违背了 web 的开放性。试想一下:如果现在所有网站只能访问自己的域名的话 web 还是现在的 web 么。那不能禁止怎么办?那就只能定一套协议把控制权交给网站所有者了。
    BeautifulSoap
        24
    BeautifulSoap  
       2022-03-26 21:43:45 +08:00 via Android
    (那么为什么浏览器不能分辨是哪个网站发起的请求呢?为什么浏览器不能在检测到是 a.com 发出的请求时,不携带 b.com 网站保存的 cookie 呢?)


    LZ 你难道不知道 js 是可以获取到当前网站的 cookie 的吗。黑客想办法在目标网页内插入了一段 js ,没有同源策略的话这段 js 可以直接获取到用户 cookie 然后直接发给给黑客的服务器(这里说的发送是构造 xhr 请求把 cookie 当参数或 post 之类的请求体发出去)
    lscho
        25
    lscho  
       2022-03-26 21:58:17 +08:00   ❤️ 1
    "那么这个同源策略到底保护的是什么呢?"

    同源策略保护的是当某个站点存在 xss 漏洞、csrf 漏洞时,其他站点不会被影响。

    “那么为什么浏览器不能分辨是哪个网站发起的请求呢?为什么浏览器不能在检测到是 a.com 发出的请求时,不携带 b.com 网站保存的 cookie 呢?”

    可以,但是浏览器不能代替网站服务提供商做出决定。跨域请求时是否携带 cookie 、以及是否响应的、响应哪些请求权利要交给网站服务提供商来决定。所以这就是如今的同源策略。

    以上是我的理解。
    wheelg
        26
    wheelg  
    OP
       2022-03-26 22:08:44 +08:00 via iPhone
    @BeautifulSoap 目前的同源策略无法防止你说的这种情况哦,如果黑客已经在你的网站里插入了恶意代码,他完全可以直接访问他自己的服务器,只需要用 cors 跨域就可以了。
    cxtrinityy
        27
    cxtrinityy  
       2022-03-26 22:09:18 +08:00
    浏览器可以分辨是哪个网站发起的请求, 不然 header orgin 字段没法填吧.
    不允许跨域请求带 cookie, 这属于一刀切了吧, 有些网站是允许跨域请求那怎么办, 比如社交网站, 第三方网站添加分享链接, follow 之类的或其他的某些功能需要识别身份的 cookie 呢
    CORS 可以保护 CSRF,但 CSRF 也可以用 CSRF token 来处理, 但某个允许跨域请求的网站在跨域时没有 CSRF token , 那 CORS 不就有用了么
    保证一个网站无法读取另一个网站的本地数据就安全这个说法有错, CSRF 并不需要恶意网站读取你的 cookie, 而是浏览器读取 cookie, cookie 对于恶意网站即使是黑盒也是可以的, 恶意网站加载时就可以发起跨域请求, 因为虽然是跨域, 但是对于浏览器来说只是发起了一个对目标网站的请求, 如果该请求的 url 符合 cookie 的发送范围, 那 cookie 就会被带上, 假设该 cookie 是用于身份验证, 恶意网站的目的只是借此通过验证, 而不是偷窃 cookie, 接下来完成验证后的操作才是 CSRF 的目的
    wheelg
        28
    wheelg  
    OP
       2022-03-26 22:11:16 +08:00 via iPhone
    @lscho 第二个解释里,浏览器如果不能代替网站提供商做决定的话,就更不需要如此严厉的同源策略才对,应该把这些东西都交给 js 去控制,这不是更好吗?
    jiangzm
        29
    jiangzm  
       2022-03-26 22:12:21 +08:00   ❤️ 3
    同源策略就是设置一个方法可以阻止非预期的请求,但是又允许非同源之间的可访问性。

    浏览器当然能知道是哪个网站发起的请求所以自动会带上 referer 方便服务端检测

    浏览器不能简单粗暴的直接禁止跨域携带 cookie ,这个选择权得交给客户端,因为太多网站应用需要相互访问

    同源策略保护谁就是第一句话提到的,阻止非预期的请求,你用 postman 或者浏览器 get 请求这还属于预期请求当然不用禁止, 那什么是非预期的请求,比如我在我的个人网站 A 嵌入很多 B 网站的请求,互联网用户访问我的 A 网站时发起的 B 网站请求这就属于非预期的请求,B 网站默认只允许 B1 、B2 跨域访问,浏览器预检后就直接禁止了,假设开发粗心设置了允许所有域名跨域访问,也没有做拦截同时访问的又是敏感接口不就有安全问题了吗
    wheelg
        30
    wheelg  
    OP
       2022-03-26 22:23:14 +08:00 via iPhone
    @jiangzm 换个角度想想,为什么操作系统没有对本地应用程序设置类似同源策略的限制,目前的 web 应用已经基本上可以做到和本地应用一样的登录认证逻辑了吧,那为什么浏览器要格外严格呢?
    如果我在我的应用程序代码里也嵌入了很多其他网站的请求,这是不是也属于非预期请求呢?浏览器对网页如此严格的限制看起来还是有其他的原因在
    lscho
        31
    lscho  
       2022-03-26 22:32:50 +08:00
    @wheelg 交给 js 是不可能的。因为 xss 漏洞就是可以插入 js 啊。对于 http 请求说,前端的任何东西都是不安全的。必须有服务器参与这个策略才行。
    wheelg
        32
    wheelg  
    OP
       2022-03-26 22:32:59 +08:00 via iPhone
    各位可以换个角度想想这个问题,为什么浏览器对网页的限制要比操作系统对本地应用的限制要多得多?

    理论上来说,本地应用能获取到的信息、对用户系统的危害远大于网页,为什么反而是浏览器的安全措施更严格(特指网络请求方面)?仅仅是因为本地应用需要下载安装这个步骤比较麻烦吗?那如果以后应用体积越来越小,例如 App Clip 和安卓快应用这类轻量的应用也需要收到类似同源策略的限制吗?

    还是说,因为浏览器本身的历史原因,它无法做到和本地应用一样的安全性,才不得已选择了同源策略这种较为严格的手段呢?
    DOLLOR
        33
    DOLLOR  
       2022-03-26 22:37:38 +08:00
    自家网站只能请求自家接口,不是很天经地义的事情吗?
    如何分辨哪些网站是自家,哪些网站是别家呢?当然是看域名了。
    但是随着 web 的发展,又渐渐出现了“需要向别家网站请求接口”的需求,所以就有了各种跨域的技术。
    跨域需要自家和别家开发者共同协作才能做到,这就杜绝了未经许可就擅自使用别家接口的行为。
    pursuer
        34
    pursuer  
       2022-03-26 22:44:27 +08:00
    @wheelg 下载安装默认认为用户知道自己在做什么,或者交给操作系统,比如 IOS 你要发布应用要经过 App Store 审核才行。当然现在浏览器也有了不少像 FileSystem 这样的扩展浏览器边界的 API.
    DOLLOR
        35
    DOLLOR  
       2022-03-26 22:45:14 +08:00
    @wheelg

    iOS 的应用沙箱,每个应用都只能访问自己的存储空间;就连 Android 都有 /data/data/youPackageName/空间,这跟 web 的“同源策略”是相似的机制,web 的同源策略其实并不特殊。
    Puteulanus
        36
    Puteulanus  
       2022-03-26 22:45:30 +08:00
    本地应用本来就比网页危险啊,操作系统没对本地应用进行更多限制,所以现在本地应用可以肆无忌惮得扫你其他软件的数据然后上传,加密你的数据勒索,要是本地应用像 iOS 一样隔得死死的,哪儿有这些的操作空间

    本地应用哪儿来的跟网页一样的安全性
    wheelg
        37
    wheelg  
    OP
       2022-03-26 22:54:06 +08:00 via iPhone
    @pursuer 有一定的道理,不知道如果以后添加 pwa 也可以被视为“用户知道自己在做什么”的话,会不会取消一定程度的同源限制,postman pwa 版多好啊
    jiangzm
        38
    jiangzm  
       2022-03-26 22:58:35 +08:00
    @wheelg 因为浏览器多网站网站访问入口,普通软件不会保存其他域的敏感信息所以没有可比性。 如果能自由访问不同的网站那就是浏览器软件了。浏览器本身和本地应用是一样的,浏览器可以拿到本地机器的信息,但是 js 执行在一个沙盒环境,正常是不可能拿到本机的数据和攻击本机。

    假设浏览器环境不同域之间的本地数据完全隔离,那也就不用同源策略了,那这样不同 web 应用之间的请求就不可能携带敏感信息。

    所以还是那句话既要可阻止也要保证访问性。
    shiganwuguo
        39
    shiganwuguo  
       2022-03-26 23:01:02 +08:00 via Android
    安全啊
    musi
        40
    musi  
       2022-03-26 23:05:40 +08:00
    @wheelg 你这个换角度就很不合理,web 是强依赖于网络的,应用又不是。web 的程序、数据全靠网络触达,且 web 开发者是没有权限对自己的 web 做限制的(没有同源的情况下),但是你作为一个本地应用开发者,能做的限制这不是多了去了。
    duke807
        41
    duke807  
       2022-03-26 23:08:57 +08:00 via Android
    大家可以查一下 cors proxy ,不允許跨域訪問的資源用第三方 cors proxy 中轉一下就可以了,所以感覺 cors 貌似意義有限,更多的是帶來麻煩
    BeautifulSoap
        42
    BeautifulSoap  
       2022-03-26 23:17:18 +08:00
    @wheelg 嗯?“如果黑客已经在你的网站里插入了恶意代码,他完全可以直接访问他自己的服务器,只需要用 cors 跨域就可以了” 我有点好奇,你可不可以举一个具体的例子讲讲,黑客怎样才能做到? 莫非你说的是在未正确配置 CSP 的时候?
    nuk
        43
    nuk  
       2022-03-27 01:07:43 +08:00
    @rekulas 这里只是举个例子说明就算没有 cookie 的情况也是很危险的,重启的 api 这个例子举得不好,可以换成需要获取 token 再调用的 api
    jim9606
        44
    jim9606  
       2022-03-27 01:25:39 +08:00
    看这个知乎回答是不是解答你的疑惑吧。我的理解是浏览器并不想破坏“跨域表单”这个用法。

    为什么跨域的 post 请求区分为简单请求和非简单请求和 content-type 相关? - 贺师俊的回答 - 知乎
    https://www.zhihu.com/question/268998684/answer/344949204

    至于第三方 Cookies 是另一个话题。以下为个人见解可能有错:拦截第三方 cookies=跨站(cross-site)请求的响应的 Set-Cookie 头会被忽略+SameSite 属性不能为 None 。
    wazggcd
        45
    wazggcd  
       2022-03-27 01:32:17 +08:00 via Android
    @nuk img 的 src 不受同源策略影响
    IvanLi127
        46
    IvanLi127  
       2022-03-27 01:32:49 +08:00 via Android
    你说:
    那么为什么浏览器不能分辨是哪个网站发起的请求呢?为什么浏览器不能在检测到是 a.com 发出的请求时,不携带 b.com 网站保存的 cookie 呢?这样不就能同样规避此类攻击吗?就如同在浏览器直接输入 api 网址那样拿到返回结果不行吗?

    如果我前后端分离,api 的域名和 web 域名不同,不就 gg 了?而且你这种限制已经比浏览器自带的限制还大,而且静默吞 Error 。很恶心的。。。。
    Al0rid4l
        47
    Al0rid4l  
       2022-03-27 03:33:35 +08:00
    "为什么浏览器不能在检测到是 a.com 发出的请求时,不携带 b.com 网站保存的 cookie 呢?"
    仅针对这一句回答, 有没有可能, 我是说可能, b.com 其实希望接受这个 cookie 呢? 你这个方案相当于假设了 b.com 不需要这个 cookie, 直接剥夺了 b.com 的选择权, 而浏览器给了 b.com 这样的选择权
    很多人认为同源策略的目的是为了防止某类攻击, 是为了保护什么, 但是同源策略本身的意图真的是这样吗? 还是你们一厢情愿地这么认为? 同源策略仅仅是浏览器框架下为 a.comb.com 提供了一套交互的规则, a.com 索取资源需要在这个规则下完成, 而 b.com 有权利选择是否给予, 当然这一切都是仅限于浏览器框架内. 同源策略保护了什么吗? 当然的确也在某些方面提供了保护, 但那是它全部的设计意图吗? 把同源策略的目的理解为防范攻击未免过于一厢情愿和狭隘了.
    毕竟如果你真的想要不经过 b.com 的同意获取资源, 那大可以写爬虫, 但这已经脱离了浏览器框架内了, 不是同源策略要考虑的问题, 而在浏览器内, 同源策略保护了 b.com 的同时, 也给 b.com 留下了选择的权利, 而你的方案里, 显然没有给 b.com 提供任何选择的机会, 充满了独裁意味
    而如果考虑有没有必要给 b.com 这样的选择, 那当然是有必要的, 当你的业务足够多, 需要多个子域名区分, 同时又希望它们之前能够有一些资源上的交互, 并且仅限于自己公司下几个域名之间而不想给其他域名获取你的资源, 那就有必要了
    duke807
        48
    duke807  
       2022-03-27 05:05:26 +08:00 via Android
    @Al0rid4l
    如果我的網站業務足夠多,有多個域名,我每個域名都使用相似的 API 接口,通過 API 接口傳參數就可以實現資源上的交互啊,為啥一定要用 cookie 呢?

    如果是靜態資源,我服務器可以檢測用戶從哪個頁面發起的請求( refer 字段),從而選擇是否給予服務

    cors 的功能本來就應該是服務器端負責實現,不應該放到客戶端實現
    duke807
        49
    duke807  
       2022-03-27 05:08:38 +08:00 via Android
    服務器端負責實現的例子:網上經常能看到一些圖片壞掉,圖片內容變成了提示:只能在 xxx 網站觀看、不允許盜鏈。
    acthtml
        50
    acthtml  
       2022-03-27 09:56:50 +08:00
    同源策略是个有东西,网景公司发明的。
    一开始只是限制 cookie ,后面才限制 api ,主要是防止 XSS 。
    thtznet
        51
    thtznet  
       2022-03-27 10:26:51 +08:00
    我的简单理解:浏览器厂商甩锅给网站运维的一个单方面政策
    awolf
        52
    awolf  
       2022-03-27 10:39:15 +08:00
    @Biwood ajax 请求怎么分辨?
    awolf
        53
    awolf  
       2022-03-27 10:40:43 +08:00
    @Al0rid4l 我觉得就是这样,楼主估计只考虑 防御,没考虑反向,接受的情况
    rekulas
        54
    rekulas  
       2022-03-27 11:36:18 +08:00
    @musi 协议倒并没有误解,不过我们理解的漏洞情况不一样吧,我理解的是大部分情况下用户构造一个 url 即可以发送非法指令,这种情况同源策略确实无法阻止,你理解的是即使 get 也需要多步交互才能构造正确的指令,这种情况同源有效,只能说都不算错吧只是需要考虑场景,毕竟 2 种情况都存在
    wheelg
        55
    wheelg  
    OP
       2022-03-27 11:58:45 +08:00 via iPhone
    看了各位的回答后,我的理解是这样的:

    浏览器在设计之初并没有一个很好的身份认证手段,于是采用了 cookie 用作身份认证,为了鉴定用户身份,浏览器不得不每次发送请求时都带上请求网站的 cookie ,因此为了考虑兼容性,不能阻止`a.com`向`b.com`发送请求时带上`b.com`的 cookie 。

    所以为了避免恶意网站利用这个 cookie ,对于非同源请求,浏览器选择了先向服务器询问`a.com`是不是可信任的( OPTIONS 预检),得到确认后才会向服务器发送真正的请求,也就是同源策略。

    如今大部分本地应用采用的是 jwt 方式保存登录信息,因此也就避免了浏览器 cookie 的漏洞,所以不需要同源策略,虽然现在的网页也可以使用 jwt 方式认证,但是为了兼容性,浏览器依然需要使用原有的 cookie 发送策略,才会有同源策略这一限制。

    那么以后会不会出现某种新的浏览器 API ,使用此 API 时可以抛弃原有的 cookie 策略,允许开发者自由访问其他域名的请求呢?
    liaohongxing
        56
    liaohongxing  
       2022-03-27 12:00:23 +08:00   ❤️ 1
    假如你登陆了工商银行的网页 A ,网页 A 给你浏览器写了个登录 cookie , 里面有个转账接口 POST 方法 http://www.ccb.com/cn/transfer/ , 需要 POST 内容 {"uid": "我的账户 UID", "money": 100} , 发起这个 POST 需要携带 Cookie, 如果我做个网页 B ,如果没有任何跨域限制,并且携带 cookie ,你访问网页 B ,网页 B 执行这个跨域 POST 方法,这个 POST 就会成功, 从而实现无缝转账 ,直接清空你的银行账户 , 这个可以衍生到很多其他方面。用你名义发帖,用你名义发邮件等等。

    想要阻止这种方案,两个简单方法:
    1. 网页 A 的请求圈在自己网站内(也就是域名内)。除非网站 B 某些接口主动加 CORS, 但是开了 CORS 对网站 B 又不安全 ,网站 B 有 Origin 字段, 限制允许的域名
    2. 去除 Cookie, 假如没有跨域限制,网页 B 能访问接口, 但是浏览器去除了 Cookie, 访问网页 A 的接口时会提示 “未登录” ,但是某些 java 应用喜欢在 URL 里用 JSESSION 传递, 所以去除 Cookie 不一定有效 。所以需要和限制域名一起使用 。
    Biwood
        57
    Biwood  
       2022-03-27 12:09:33 +08:00
    好吧今天重读了一下才大概理解 OP 的意思。

    网页应用和系统本地应用最大的一个区别就是,本地应用不存在“跨域资源共用”这件事情,比如你打开微信,你觉得微信里面会引用迅雷提供的某个二进制代码文件吗?就算有引用,多半也还是基于网页形式,这就是网页的特殊性。在网页上这种情况却从一开始就是存在的,也正因为这种极高的复用性,才使得每个网页可以做到只有几 KB 的大小,而不是每个域名下的网页都要重新下载 CSS/JS/图片等等。

    而因为这种高度的互相引用能力,必然会导致出现一些跨域攻击的漏洞 XSS/CSRF 等,正因为及其不安全,所以才有了严格的同源策略。

    之所以成为现在这套策略,相信 W3C 以及各个浏览器厂家和互联网大厂都经过推理的,这里面有一套严密的逻辑,你既要保证各个域的资源能相互引用,又要保证引用的时候不被恶意利用。
    3dwelcome
        58
    3dwelcome  
       2022-03-27 12:36:34 +08:00 via Android
    同源限制的是,你网站 ajax ,去调用别的网站 api 的能力。
    比如我写的 gitview 网页工具,需要请求 www.github.com 的 get 方法。但这个请求没经过 github 的审批,没把我的域名放进白名单,就被浏览器代为阻止了。
    这个权限 github 后台服务器可以控制,跨域也算是一种后台对访问域名的授权吧。
    duke807
        59
    duke807  
       2022-03-27 13:36:16 +08:00 via Android   ❤️ 1
    @3dwelcome
    如果瀏覽器沒有 cors 機制
    github 服務器端可以判斷來源,然後決定是否允許本次的 api 調用,見 #49 樓舉的例子

    另我在 #41 樓有提到,目前在瀏覽器端實施的 cors 機制很容易繞過:不允許跨域訪問的資源用第三方 cors proxy 中轉一下就可以了,譬如你要訪問的連接改為 github.com/xxx/yyy 改為 proxy.zzz/github.com/xxx/yyy 就可以訪問了
    安全上根本得不到保護
    duke807
        60
    duke807  
       2022-03-27 13:43:33 +08:00 via Android   ❤️ 1
    我懷疑這麼設計主要目的是為了降低跨域引發的 DDoS 攻擊的烈度
    3dwelcome
        61
    3dwelcome  
       2022-03-27 15:03:05 +08:00
    @duke807 "我懷疑這麼設計主要目的是為了降低跨域引發的 DDoS 攻擊的烈度"

    我们想到一块去了。

    安全性是 CORS 之一,但是很多大网站安全性,比如网银转账 API ,铁定不会只依赖于 Access-Allow-Origins 设置,那样也太不靠谱了。

    光看 GITHUB CORS 对 GET 限制,就是让后台 API 不会被其他网页随意调用。万一一个大网站被挂了恶意 JS ,用大量的 AJAX 占用 GITHUB 后台访问请求,那几乎就是 DDOS 了。
    cxe2v
        62
    cxe2v  
       2022-03-27 16:19:26 +08:00   ❤️ 1
    @duke807 #59 但是这样你也拿不到 github.com 的 cookie ,因为网页是向你自己的服务器发起的请求
    duke807
        63
    duke807  
       2022-03-27 16:36:07 +08:00
    @cxe2v 理論上 第三方 cors proxy 也可以中轉 cookie
    choury
        64
    choury  
       2022-03-27 17:33:32 +08:00 via Android   ❤️ 1
    @duke807 浏览器又不会把 github.com 的 cookies 发给你的 proxy.zzz 的代理
    pppan
        65
    pppan  
       2022-03-27 17:47:30 +08:00   ❤️ 1
    SOP 的核心是防止信息泄露,和 cookie 关系不大。对于携带三方 cookie 发送跨站请求的 CSRF 攻击防护方法是使用 SameSite Cookie 、CSRF Token 等等。SOP 不能阻止你发送请求,因为很多接口是可以通过简单 GET/POST 触发的,`<img src="http://localhost/reboot">` 同样可以触发。但是 SOP 可以防止你收到请求的返回,通过 js 从跨站接口窃取用户数据。
    Al0rid4l
        66
    Al0rid4l  
       2022-03-27 18:10:13 +08:00
    @duke807 我从来就没有说过一定要用 cookie, 我只是针对楼主的问题作出回答, 请不要把这样的观点强加到我身上
    而针对你说的, 你用 refer 也可以选择是否给予服务, 的确, 但这只是你 a.comb.com 私下的协议, 浏览器并不知情, 确实如你所说你自己做好判断能够保证资源不被其他站点获取, 一方面这仅仅针对 http 请求, 另一方面这样私下的协议浏览器并不知情. 当然你可能会问为什么要浏览器知情? 如果每个开发运维人员都能够很好的做好安全措施, 那这个世界的确会美好很多, 但显然不是这样的, 依靠这些判断来保证安全增大了开发和运维的心智负担, 大部分人都做不好, 而浏览器作为 web 的入口, 他选择承担让 web 更安全这样的责任, 提供了这样的机制, 是有意义的
    而回到这个帖子, 我不知道为什么这么多人把目光都放在 cookie token 这样的东西上, 同源策略不仅仅是针对这些东西的, 它限制的内容很多, 而 cookie 仅仅是其中之一而已.
    事实上同源策略还限制了很多 js API, 包含了跨域写, 跨域读, 跨域嵌入资源几个方面, 而限制主要体现在跨域读这件事情上, 比如 a.com 引用了 b.com 的图片, 如果没有 cors 允许, 那 a.com 页面的 js 不能读取图片的二进制内容, 而图片的二进制内容可能泄漏敏感信息, 当然这个例子可能并不能感受到, 一个图片能泄漏什么敏感信息. 但同样的, 假如 a.com 用 iframe 嵌入了网银登录页面, a.com 的 js 能够读取嵌入页面的变量, hook 里面的函数, 那显然是有问题的. 当然你也可以用 X-Frame-Options 来防止 iframe 嵌入, 但是同样地, 如前面所说, 并不是每个人都知道使用这些来保证安全, 而浏览器替他们完成了这一保障总是好的
    Al0rid4l
        67
    Al0rid4l  
       2022-03-27 18:11:28 +08:00
    @pppan 这么多回复里就这个说到点子上了
    cyrbuzz
        68
    cyrbuzz  
       2022-03-27 19:33:32 +08:00
    浏览器目前的做法就是如你所说的,所以你的疑问并不存在= =,看 MDN:

    `https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E9%99%84%E5%B8%A6%E8%BA%AB%E4%BB%BD%E5%87%AD%E8%AF%81%E7%9A%84%E8%AF%B7%E6%B1%82`

    XMLHttpRequest 或 Fetch 与 CORS 的一个有趣的特性是,可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨源 XMLHttpRequest 或 Fetch 请求,浏览器 **不会** 发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。


    如果想要携带 cookies ,必须在发起请求时要求 XMLHttpRequest 或者 Fetch 携带 cookies ,并且服务器也需要允许`Access-Control-Allow-Credentials: true`,且附带 cookies 的情况下,其他跨域属性均不能为通配符,必须指定一个准确的值。
    ljpCN
        69
    ljpCN  
       2022-03-27 21:14:30 +08:00
    @wheelg #32 app 发布需要应用商店审核,网站只要你开放一个 http 端口就行,自然浏览器需要防范得比操作系统更多。
    aecra1
        70
    aecra1  
       2022-03-28 01:51:23 +08:00
    没有同源策略钓鱼网站就能变成真网站。
    chnwillliu
        71
    chnwillliu  
       2022-03-28 10:05:11 +08:00 via Android
    大家都不审题啊,楼主没说浏览器为什么要同源策略,楼主是说为什么浏览器不能一刀切死,每个网站一个沙箱,大家各自井水不犯河水。

    同源策略就是一套带着枷锁跳舞的规则,一方面要给到开发者一定程度的自由,一方面还要保证安全性。
    HelloAmadeus
        72
    HelloAmadeus  
       2022-04-16 14:17:03 +08:00
    @wheelg 我尽量解释清楚哈,steampowered.comsteamstatic.com 都是 steam 的 domain ,但是 steam.com 不是,假如不加入没有同源策略,steam.com 就可以攻击 steampowered.com 的用户,(添加 src 或者页面伪装一下)。假如同源策略严格到域名必须一致, 那么 steampowered.com 就无法和 steamstatic.com 共享 cookie ,这对网站维护方太麻烦了,不能为了安全一刀切。
    至于 postman 发送是另外一回事了,当用户使用 postman 带 cookie 请求的时候,是用户主动行为,不属于黑客攻击了。举个例子,很多抢购工具都依赖 cookie 登录,需要用户把浏览器中登录 cookie 设置好然后用软件发送请求抢购,显然用户是知道这个行为的,和跨域攻击没有关系。
    所以先了解跨域攻击,知道其边界在哪里,问题就自然而然明白了。这也是初入一个领域学习的要领,遇到问题先不要急于下手,而是先去准确定义问题,先去刨根。比如现在这个问题,为什么选择了如今同源策略?定义问题的过程中就会有,什么是同源策略?跨域攻击是什么?同源策略解决了跨域攻击中哪些问题?所以我才让你去了解跨域攻击。
    希望能帮到你。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1644 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 16:48 · PVG 00:48 · LAX 08:48 · JFK 11:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.