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

响应头设置 Access-Control-Allow-Origin 的意义何在?

  •  1
     
  •   raw0xff · 42 天前 · 2430 次点击
    这是一个创建于 42 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务端响应头设置 Access-Control-Allow-Origin 貌似只是告诉客户端一个白名单,让客户端自觉建立连接,那如果客户端不自觉呢?服务端是不是还需要对 origin 进行判断来决定是否拒绝访问?那 Access-Control-Allow-Origin 的意义何在?

    25 条回复    2024-11-15 09:29:53 +08:00
    lisxour
        1
    lisxour  
       42 天前
    这些头绝大部分情况下是针对于浏览器的
    Quarter
        2
    Quarter  
       42 天前 via Android
    这个本来就是双端一起努力的结果,所以才好推广官方浏览器,不要用不知道哪里下载的浏览器,以及,如果你自己开发一个浏览器,其实可以绕过很多安全策略的,比如 ssl 证书检测、跨域策略等等
    DOLLOR
        3
    DOLLOR  
       42 天前
    1 、标准的 web 浏览器是自觉的,不自觉的浏览器没人敢用。

    2 、非必要,但可以。取决于你的网站对安全的需求。

    3 、意义是区分资源所有者。
    web 是利用域名来区分服务提供商的。
    自己网站只能访问自己的接口,自己的接口只能被自己的网站访问,是天经地义的事情。
    Puteulanus
        4
    Puteulanus  
       42 天前
    对 origin 进行判断也没用,后端安全的一个原则就是客户端发过来的所有东西都可能是不可信的
    cors 头不是用来保证后端安全的,是给后端一个操纵前端(浏览器)行为的 API
    codehz
        5
    codehz  
       42 天前
    其实这些限制是保护普通用户的,不然人家在钓鱼网站里弄几个请求(同时带第三方网站的 cookie )把你钱转走了就出大问题了,客户端的话,系统也直接不让你访问其他应用的数据
    Akitora
        6
    Akitora  
       42 天前 via Android
    这是给标准浏览器看的
    raw0xff
        7
    raw0xff  
    OP
       42 天前
    @Puteulanus
    “后端安全的一个原则就是客户端发过来的所有东西都可能是不可信的” 学到了。
    “是给后端一个操纵前端(浏览器)行为的 API” 操控换成约束也不对,毕竟无法约束更无法操控,像 @Quarter 说的“是双端一起努力的结果”比较贴切。
    ShineyWang
        8
    ShineyWang  
       42 天前 via Android
    君子协定
    正规浏览器都会有 cors 报错

    postman 这种就不会管

    所以假如你信任你的电脑,信任你安装的浏览器
    那这个就是有效的
    huijiewei
        9
    huijiewei  
       42 天前
    不自觉的客户端谁敢用啊。真是的
    Y25tIGxpdmlk
        10
    Y25tIGxpdmlk  
       42 天前
    那是告诉正规的浏览器的,正规浏览器都会遵守这个规定,不然用户数据就得不到保障了。

    chrome 也可以用--disable-web-security 这个命令关闭安全设置。

    当然你自己写的各种 py ,或者其他脚本,可以随便忽视这个头。
    restkhz
        11
    restkhz  
       42 天前   ❤️ 2
    楼主感到疑惑:貌似只是告诉客户端一个白名单让客户端自觉连接,服务端是不是还要判断 @$%^&%
    楼主可能知道这是什么,但是不知道这个目的是什么...我们从头来说吧

    5 楼说了安全问题。是的。如果 A 网站能读取浏览器保存的 B 网站的 Cookie ,或者 A 网站的脚本能随意让浏览器对 B 网站发起请求(比如转账操作),是不是不安全?

    于是搞了一个同源策略。如果非同源,即便要求发 Ajax 也会拒绝。非同源就 0 信任。
    但是这样的同源策略是否有些过于严格?

    如果我前后端分离,我域名或者端口就是不一样怎么办?我前端就是需要加载别的域名的 API 怎么办?反正我就是要加载非同源的东西,你一个同源策略因为安全问题就把它堵死了?搞得 AJAX 用不了。

    楼主说的 Access-Control-Allow-Origin 这就来了。
    后端需要告诉浏览器,哪个前端网站你可以信任,在他的页面可以给我发请求,我们是一家的。

    这是设置一种因为信任而可以设置安全例外的做法。

    客户端不自觉?那是客户端有安全缺陷。你做网站的恐怕做不了太多。
    AoEiuV020JP
        12
    AoEiuV020JP  
       42 天前
    就是表个态而已,chrome 完全可以用插件或者启动参数关闭 cors 错误,
    保护的是懵懂的用户,避免误上套壳网站比如 iframe 嵌套你的网站,这种用户数据有泄露风险,设置那个就会报错 cros ,
    ochatokori
        13
    ochatokori  
       42 天前 via Android
    浏览器就是自觉,减少让你点个链接就被黑了的情况
    importmeta
        14
    importmeta  
       42 天前
    这个只针对浏览器, 但不针对 Postman 这种.
    xiangyuecn
        15
    xiangyuecn  
       42 天前
    不是为了限制,这个头存在的意义是为了解除限制,允许别人访问你的资源,默认拒绝
    xy2401
        16
    xy2401  
       42 天前
    代理检测:在线检测您是否在使用 Clash
    Clash 检测工具的原理
    https://v2ex.com/t/1076961
    之前的帖子正好于此有关

    搞清楚 客户端 a 网站 / 服务端 b 网站 / 浏览器 这三方谁有可能恶意
    IvanLi127
        17
    IvanLi127  
       42 天前
    这个保护的是终端用户,减少用户成为肉鸡的可能,保护用户的信息安全,大概这意思。和服务端的安全嘛...没啥关系
    iOCZS
        18
    iOCZS  
       42 天前
    你要明白,发送请求的是浏览器,跨域也是浏览器的限制,浏览器是诚实的,不诚实的是你的脚本
    raw0xff
        19
    raw0xff  
    OP
       41 天前
    @restkhz 特别喜欢能够站在提问者角度讲解的答主,感谢。
    浏览器访问 a 网站时 a 网站的脚本访问 b 网站,无论是 post get 还是 options ,是否响应是 b 网站自身逻辑说的算的,即便 Access-Control-Allow-Origin:* 也只是告诉浏览器 b 允许所有来源访问,至于如何响应是看代码。那么 b 网站设置 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 的意义是啥?后端不可能只声明不处理,curl postman 就能钻空子,声明了还是需要处理,那为啥还要声明?一定是某个场景需要,我就这点没搞懂。
    xxxccc
        20
    xxxccc  
       41 天前
    @raw0xff 本质上是为了 css 攻击的
    restkhz
        21
    restkhz  
       40 天前
    @raw0xff 你没搞明白的是谁在防谁。
    这个机制不是让你服务器防着恶意客户,而是让正常客户防第三方网站的攻击。防止第三方攻击者在正常客户的浏览器中模拟正常请求访问你的接口。这个是在保护浏览器安全,不是保护服务器安全。

    你的客户可能在第三方网站被钓鱼,假设没有同源策略,假设你是银行,此时恶意的第三方网站里有个脚本会在用户浏览器里运行:自动模拟你网站的转账操作,发给你的接口。由于没有同源策略,这个请求因为带着你客户的 cookie 等信息。你的客户就这样莫名其妙被偷了钱。

    或者你是一个 webmail 但是人家也可以通过类似手段,在三方钓鱼网站里插脚本控制用户浏览器,进而偷到你客户的邮件。

    你说请求在接口处理与否取决于你的代码,但是这个伪造的请求千真万确是客户端浏览器发的。看似完全正常的请求,正常的 Cookie ,同样的 IP 。Referer 头不靠谱而且可能被绕过,你说用 Token 但是 Token 也可能被偷(如果没有同源策略)。你服务器要怎么检查??

    因为这种攻击发生在客户端,所以客户的浏览器实现防御才比较容易。
    于是有了同源策略 SOP ,注意,SOP 不阻止请求发出,但是可以阻止带着 Cookie 。还有非同源页面能否读网站响应。

    你会发现请求不带 Cookie, 同时脚本不能跨源读数据,
    上面说的两种攻击基本上就被阻断了。(当然实际情况更复杂些)
    但是前后端分离也同样被阻断了。


    你说的:
    > "浏览器访问 a 网站时 a 网站的脚本访问 b 网站,无论是 post get 还是 options ,是否响应是 b 网站自身逻辑说的算的,即便 Access-Control-Allow-Origin:* 也只是告诉浏览器 b 允许所有来源访问,至于如何响应是看代码。"


    带上 SOP 以后,由 a 发起的访问 b 网站的请求不会带有 b 的 cookie ,响应也未必能被 a 的页面读取。敏感操作和敏感信息都 a 都搞不了。

    而 Access-Control-Allow-Origin 是 CORS 的一部分,作为同源策略 SOP 的扩展,允许你提供接口的服务器指定哪个网站可信(可以发 cookie 和可以读响应),就是告诉浏览器第三方网站的白名单,白名单里的网站应该不会让浏览器发恶意请求,可以让 SOP 信任。CORS 给开发部署提供一些灵活性。这样你又可以前后端分离了。

    顺便,你设置成 Access-Control-Allow-Origin:*的时候,浏览器的 Cookie 是不会发出去的。这整套机制都是怕浏览器被第三方恶意网站利用。
    至于调试工具,,你不用调试工具当日常浏览器,不用担心被钓鱼,而且 CORS 也要被调试。所以当然不遵守这些。

    楼上有人说的 CSS 应该是 XSS. 那个是 CSP 机制的事情。因为恶意脚本插入正常网站后是同源的。
    cndenis
        22
    cndenis  
       40 天前
    OP 是做服务端的吧, 不理解 CORS 的存在的意义也正常, 我以前也是这么想的. 后来发现这是不同领域的问题, CORS 不是服务端安全需要的东西, 而是要解决的是前端安全的问题, Access-Control-Allow-Origin 是 CORS 的一部分, 是服务端配合前端做的配置.

    浏览器需要 CORS 的根本原因是因为需要在 "同一个浏览器" 访问 "不同的网站", 你的网银和诈骗网站是在同一个浏览器上访问的, 尽量避免诈骗网站访问你的服务器是浏览器的任务, CORS 配置就是帮助浏览器完成这个任务而产生的.

    因为诈骗网站不在你的域名下, 设置了 Access-Control-Allow-Origin:[你的域名], 浏览器就会阻止诈骗网站向你的服务器发起请求. 这样就实现了浏览的安全.

    一般而言 APP 不需要 CORS, 因为一般的 APP 中访问都是写死服务器地址, 不会让用户输入和访问其他域名, 也就没有在 APP 中运行诈骗网站代码的机会, 所以一般来说不需要 CORS.
    DICK23
        23
    DICK23  
       40 天前
    这玩意儿本来就是让客户端自己判断的,服务端只是给你提个醒,能不能过看你自己
    raw0xff
        24
    raw0xff  
    OP
       37 天前
    @restkhz
    @cndenis
    我想我知道 SOP CORS 和 CSP 的用法的,我也知道 CORS 是保护用户浏览器中的数据安全而不是服务器安全。但是我想不到一个场景“后端无须参与,单凭前端既可确保不被攻击”。如果没有这种场景的话,那必须就有后端判断来源合法恶性,那么还需要后端进行 CORS 设置干嘛?
    cndenis
        25
    cndenis  
       36 天前
    @raw0xff 服务端的配置是给前端提供判断的依据, 不设置的话浏览器不知道哪些是合法的哪些是不合法的.

    比如说你同时在浏览器访问银行网站 bank.com 和 恶意网站 evil.com, 你访问 bank.com 的 session/token 就存在浏览器里, 浏览器就要帮你隔离这两个站点的数据, 避免 evil.com 能拿到这些 session/token.

    假如 evil.com 通过某些手段拿到拿到了 token, 带着合法的 token 要你向我转账 1000 元, 后端是没有办法判断这条请求是来自 bank.com 还是 evil.com. 要实现安全就需要浏览器配合, 不可能是纯后端的事.

    你可能会说转账这事很关键, 服务端会加更多的验证的机制, 要求手机/证书等等, 但不是每个请求都会有这么多的安全措施的, 比如在 v 站发个贴子就不能要求插着 U 盾才能发吧. 这时浏览器的防御就能起到保护效果.

    安全里有一个理念叫纵深防御, 即使后端有判断, 前端也要做判断. 这样能增大攻击成本, 提高安全性.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1399 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 17:24 · PVG 01:24 · LAX 09:24 · JFK 12:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.