same-site和same-origin

必须要说same-site和same-origin这两个概念是有区别的,我以前经常弄混…

Origin(源)

same-origin

Origin是由协议(scheme/protocol,比如http或者https),主机名(host name)以及端口号(port,不一定有)构成,比如一个url为https://www.example.com:443/foo,那么这个url的origin就是https://www.example.com:443

因此,不同的网站如果协议、主机名以及端口号都是相同的,那么它们之间就是”same-origin”(同源),否则称之为”cross-origin”(跨域)。

Origin A Origin B 关系
https://www.example.com:443 https://www.evil.com:443 跨域:域名不同(different domains)
  https://example.com:443 跨域:子域名不同(different subdomains)
  https://login.example.com:443 跨域:子域名不同
  http://www.example.com:443 跨域:协议不同
  https://www.example.com:80 跨域:端口号不同
  https://www.example.com:443 同源
  https://www.example.com 同源(默认端口号一致)

Site(站)

same-site

Root Zone Database数据库里面列出了所有比如.com.org这样的顶级域(Top-level domains , TLDs)。Site的意思就是TLDs和它前面的域(domain)的一部分所构成。比如对于urlhttps://www.example.com:443/foo来说,它的site就是example.com

但是比如说.co.jp或者是.github.io这样的域来说,如果是按照上面的定义从.jp或者是.io这样的TLDs出发去定义,显然这样并不准确。这样就需要一个标准Public Suffix List去定义网址中有效的TLDs(effective TLDs, eTLDs),这个列表publicsuffix.org/list列出了所有的eTLDs。

因此整个网址名也就是site可以看作eTLD+1,比如urlhttps://my-project.github.io,那么它的eTLD就是.github.io,eTLD+1也就是site即my-project.github.io

same-site

所以网站之间如果有相同的eTLD+1,那么它们就是same-site(同站),反之就是cross-site(跨站)。

Origin A Origin B 关系
https://www.example.com:443 https://www.evil.com:443 跨站:域名不同(different domains)
  https://example.com:443 以下皆为同站
  https://login.example.com:443  
  http://www.example.com:443  
  https://www.example.com:80  
  https://www.example.com:443  
  https://www.example.com  

schemeful-same-site

以上所说的same-site是没有考虑协议(scheme/protocol)的,但是因为安全性问题,same-site有时需要考虑协议相同,也就是schemeful same-site,因此http://www.example.comhttps://www.example.com视为cross-site。

如何判断请求request是”same-site”, “same-origin”, 还是 “cross-site”?

Chrome在发送请求时会带有Sec-Fetch-Site这样的HTTP header,目前其他浏览器并不支持Sec-Fetch-Site。属性值可以对请求进行相应的判断。