域名小知識(shí):Public Suffix List
Webkit 中,通過 document.domain,可以將 domain 設(shè)置到最后一級(jí)(最后一個(gè)點(diǎn)之后的內(nèi)容)。由于域名最后實(shí)際上有一個(gè) .(例如https://imququ.com. 可以正常訪問), 所以甚至可以將document.domain 設(shè)置為空字符串。
根據(jù) HTML5 文檔的描述:在 JavaScript 中通過 document.domain 設(shè)置當(dāng)前頁面的 domain 時(shí),如果新值不等于當(dāng)前值,也不是 IPv4 和 IPv6 格式時(shí),需要判斷新值是否在 PSL(Public Suffix List,公共后綴列表)中,如果存在必須拋出 SecurityError,終止后續(xù)流程。
PSL 是由 Mozilla 創(chuàng)建的公共資源,官網(wǎng)是 publicsuffix.org。它由兩部分組成:一部分是由 ICANN(The Internet Corporation for Assigned Names and Numbers,互聯(lián)網(wǎng)名稱與數(shù)字地址分配機(jī)構(gòu))提供的 TLD(Top Level Domain,頂級(jí)域名)列表;一部分是由個(gè)人或機(jī)構(gòu)提供的 PRIVATE 列表。完整的 PSL 可以從這個(gè)地址獲得。
ICANN 維護(hù)的 TLD 列表好理解,例如最常見的 com、net、org 等等都屬于這個(gè)列表。為大家所熟知的 TLD 最多也就幾十個(gè),那么完整的 TLD 列表包含多少記錄呢?我統(tǒng)計(jì)了一下,截至到當(dāng)前:
TLD 列表中一共有 7247 條記錄;
最長的記錄有 35 個(gè)字符,例如:posts-and-telecommunications.museum;
級(jí)別最多的記錄有 4 級(jí),例如:pvt.k12.ma.us;
PRIVATE 列表由個(gè)人或機(jī)構(gòu)自行添加。例如我想把 imququ.com 的二級(jí)域名開放給其它人使用,同時(shí)還想讓這些二級(jí)域名之間相互隔離,我可以申請(qǐng)?jiān)? PRIVATE 列表中加上 imququ.com。目前在 PRIVATE 列表中,有很多都是 Amazon Web Services 添加的,目的就是為了隔離用戶。
現(xiàn)在很多提供 App Engine 服務(wù)的廠商一般都會(huì)給用戶提供二級(jí)域名,例如 example.duapp.com,這會(huì)帶來很大的安全隱患:假如用戶將 document.domain 設(shè)置為大域;或者在設(shè)置 cookie 時(shí)指定 domain 為大域,都會(huì)導(dǎo)致網(wǎng)站完全暴露給其它二級(jí)域名用戶。那如果用戶在使用過程中避免了這些問題,是不是就高枕無憂了呢?也不是!其它用戶如果在大域?qū)懭氪罅? Cookie,一樣可以對(duì)你的二級(jí)域名造成拒絕服務(wù)攻擊,想了解細(xì)節(jié)的同學(xué)請(qǐng)看這篇文章:超大 Cookie 拒絕服務(wù)攻擊。
這也是為什么亞馬遜要把那么多 AWS 域名都加到 PSL 的 PRIVATE 列表中的原因。國內(nèi)的服務(wù)商,我看到 Sina 的 SAE 也做了相關(guān)處理,這一點(diǎn)上 SAE 確實(shí)比較細(xì)致。
目前 PSL 中的 PRIVATE 記錄統(tǒng)計(jì)如下:
PRIVATE 列表一共有 557 條記錄;
最長的記錄有 36 個(gè)字符,例如:ap-northeast-1.compute.amazonaws.com;
級(jí)別最多的記錄有 5 級(jí),例如:s3.cn-north-1.amazonaws.com.cn;
二者加起來,完整的 PSL 一共有 7804 條記錄。
PSL 做為公共資源,可以被用在很多場(chǎng)景上,例如 Firefox 用它在地址欄高亮 URL 的關(guān)鍵部分。PSL 更重要的用途是用在瀏覽器同源策略上:例如通過 document.cookie 設(shè)置 cookie,或者通過 document.domain 設(shè)置當(dāng)前 domain,都不允許將 domain 設(shè)置為 PSL 中的記錄。
Webkit 一直以來只在設(shè)置 cookie 時(shí)使用了 PSL,前面提到的 Chrome 的那個(gè) Bug 純屬從 Webkit 繼承而來。大約在兩年前(詳情),Chrome 解決了這個(gè)問題。以下分別是用最新的 Chrome、Firefox 以及 Microsoft Edge 的測(cè)試結(jié)果:
然而,Safari 至今為止依然沒有修復(fù)這個(gè)問題,以下是在最新的 Safari 中的測(cè)試結(jié)果: