blog

Anson's working / exploring footprints 🧙‍♀️

View on GitHub

同源策略

Terms

ORIGIN = PROTOCOL(also called SCHEME) :// HOSTNAME : PORT(if specified)

SAME ORIGIN needs above three factors be the same
SAME SITE needs only the hostname‘s eTLD+1 is same

Resources Load

  • js(nomodule)、css、img、documfireent、ws(会带上 origin)跨域请求,无需 cors 配置
  • js(module)、xhr、font 跨域请求,需要 cors 配置
  • web worker/service worker 不允许跨域,配 cors 也不行,需用 blob url

Secutiry Strategy

CORS

  • 浏览器发起 cors 简单请求时会自动带上 origin 字段,值为页面(有 iframe 时为 iframe )的 origin,需要返回能匹配此 origin 的 Access-Control-Allow-Origin
  • Access-Control-Allow-Origin 只允许 origin 或者 *, 支持多个 origin 需要动态处理
  • 浏览器 document.cookie set 值时 domain/path 默认值从浏览器 url 获取,http 返回 set-cookie 时,domain/path 默认值从 http url 里获取,domain 的默认值是 hostname,path 的默认值是路径,example url: https://www.example.com:1234/path/to/api, domain 默认值是 www.example.com,path 默认值是 /path/to
  • 显式设置了 domain 时加不加 prefix dot 都会被浏览器加上,变为子域可用; 未设置时仅对当前 domain 默认取有效,子域无法匹配
  • httponly 的 cookie 不允许 js 读取和修改,但通过 devtool 可以
  • cookie 的 domain 比较不区分 PROTOCOL(未指定 secure 字段时) 和 PORT
  • cookie 只会携带 name 和 value,其他字段都是为浏览器安全设计的,不会携带
  • 当浏览器 document.cookie 存在相同 name 的 cookie 时(domain/path 不同,但都匹配上了),都会携带到服务器
  • value 可以为设为空
  • 删除用 max-age=0
  • name、domain、path 都匹配时(domain、path 未设置时取默认值),才能触发删/改操作,否则触发新增,其它 SameSite、Secure 等字段不匹配时,不会触发新增,而是覆盖之前的字段值(不设置就是用默认值覆盖 Lax/false)
  • cookie 的 domain 和 path 字段仅用于匹配 cookie(跟跨域判断以及 SameSite 都无关), 并且匹配是相对于请求 url 本身(url contain sub domain/path could visit it’s parent filed cookie, but not vice versa),不是其他外层 url
  • CORS 时要携带 cookie,首先客户端 fetch 设置credentials: "include" 参数用于决定是否携带,一旦设置,服务端返回头 Access-Control-Allow-Origin 要指定域名不能用 *,同时设置 Access-Control-Allow-Credentials 字段为 true,浏览器才会使 reponse 生效。注意这里只是浏览器拒不拒绝,cookie 只要携带出去,请求再服务端就已经完成了,CSRF 就是用了这个特性
  • 带 cookie 跨域请求完成链条,匹配上(出去)-> 设有 xhr 的 withCredentials 或 fetch 的 credentials(出去)-> 过 SameSite(出去)-> 过 cors(回来)

Iframe

  • iframe 内 xhr 请求的跨域判断(就包括 cookie 携带的跨域判断)是请求地址的 origin 相对于 iframe src 的 origin (SAME ORIGIN), 不是相对于浏览器导航栏地址的 origin
  • cookie SameSite 判断是请求地址的 site 相对于浏览器地址栏 url 的 site (SAME SITE),不是内层 iframe src 的 site, 采用 SameSite 之前依赖 csrf-token 解决 CSRF 问题
  • iframe 内部请求是否可以携带 cookie 以及是否可以 set-cookie 在 cross-site 时受 SameSite 默认行为 Lax(since chrome 80,Safari、FireFox 未支持) 管控. SameSite 属性可通过 js 操作 cookie 修改(firefox 不允许客户端修改), 但无法操作跨域 cookie, 因此 CSRF 就基本杜绝了
  • 跨域不允许操作不同源的 DOM 是指不同 iframe 或 tab 的 DOM 无法互访, 而不是指跨域加载的脚本不能操作当前页面的 DOM. 脚本只要 CSP(XSS killer) 允许执行, 就能操作

Domain Hack

Different subdomains’s domain value a.example.com | b.example.com could be updated by document.domain = 'example.com'.After this change, we get a same origin. Now different subdomains page could access each other’s window and domcument object, therefore DOM、Cookie、Localstorage、Indexdb operation are all available.

Restrictions:

  • Domain can only set to current domain’s suffix, but root domain is not allowed(the same rule as cookie domain field setting by js)
  • Both subdomains need do document.domain set operation, even if one of them has already been the target domain
  • Protocol need same (Mixing http and https is not allowed)
  • Port is not display in document.domain, and each domain use different port number doesn’t matter
  • After chrome 112, document.domain will be readonly, unless all domains set a Origin-Agent-Cluster: ?0 header
tags: browser