HTML rel 屬性:noopener 與 noreferrer 的差異及安全性應用
此文章是 FrontendMaster 上的 Advanced Web Development Quiz 課程筆記
問題
Which statements are true? Select all the correct answers.
[1] rel=noopener is used to prevent the original page from accessing the window object of the newly opened page.
[2] rel=noreferrer can be used to prevent the newly opened page from accessing the window object of the original page.
[3] rel=noopener and rel=noreferrer can only be used with HTTPS.
[4] rel=noopener can be used to prevent tabnabbing.
[5] The default value for the Referrer-Policy is no-referrer-when-downgrade.這一題在比較 <a> 標籤的 rel 屬性:noopener、noreferrer 的行為差異。
在瀏覽器中使用 <a> 標籤時,如果屬性加上了 target="_blank",可以透過 rel 屬性來調整開啟的頁面對原頁面的存取權限。
rel="opener"
<a href="sample.com" target="_blank" rel="opener">Link</a>
當設定了這個值,開啟的頁面可以透過 window.opener 取得前一個頁面的 window,如此一來新頁面就可以透過 window.opener.location = "phishing.com" 來做到惡意攔截的攻擊 (tabnabbing),通常這個設定只會使用在可信任的內部頁面且有需要雙向 window 通訊時才會使用。
rel="noopener"
<a href="sample.com" target="_blank" rel="noopener">Link</a>
這個是預設值。相較於 opener,設定 noopener 時,新開的頁面執行 window.opener 時,只會得到 null,不過舊版的瀏覽器仍然需要明確指定這個值比較保險。
window.open()也支援這個參數
rel="noreferrer"
首先,這個值會同時啟用 noopener 的效果。接著它的效果是會讓新頁面的 document.referrer 回傳空字串,這樣子就可以避免洩漏網址上的參數 (query),也許有時候會有一些敏感的值 (例如使用者 ID)。
舊版瀏覽器上建議可以寫完整
rel="noopener noreferrer",有些可能只支援noopener
啥都不加
如果什麼都不寫,那麼開啟的頁面就可以從 window.opener、document.referrer 取得來源網站的 window 與完整網址
所以在設定連結會開啟新頁面並連到外部網站時,在 rel 加上 noopener noreferrer 會是最理想的做法
額外補充 Referrer-Policy 預設值變更
瀏覽器的預設 Referrer-Policy 曾是 no-referrer-when-downgrade,表示從 HTTPS 跳轉到 HTTP 時不發送 Referer header,以避免敏感資訊洩漏到不安全連線。
現在已變更為 strict-origin-when-cross-origin,在跨域請求時僅發送 origin(例如 https://www.website.com),不包含路徑或查詢參數,提升隱私保護。
答案
[2] rel=noreferrer can be used to prevent the newly opened page from accessing the window object of the original page.
[4] rel=noopener can be used to prevent tabnabbing.