使用noopener和noreferrer讓HTML中的外部鏈接更安全
前言
剛學(xué)前端那會兒,我處理外鏈的方式簡單粗暴:
<a >隨便一個外鏈</a>
點(diǎn)一下,當(dāng)前標(biāo)簽直接跳走。 用戶剛打開好不容易進(jìn)來的頁面,下一秒——嗖地沒了。
后來我發(fā)現(xiàn) target="_blank" 這個“神器”:
<a target="_blank">在新標(biāo)簽打開的外鏈</a>
從此以后,外鏈都乖乖在新標(biāo)簽里打開:
原頁面留在那兒
新內(nèi)容另起一頁
體驗(yàn)一下子順眼了很多,我自己也用得很爽。 直到有一天,我才知道:
只加
target="_blank",你其實(shí)給自己埋了一個安全坑。
問題不在“新標(biāo)簽”,而在它背后悄悄多出的那根“線”
當(dāng)你用 target="_blank" 打開一個新標(biāo)簽時, 瀏覽器會在兩個頁面之間,悄悄建立一條 JavaScript 通道。
具體來說:
新開的頁面,可以通過一個叫
window.opener的對象, 直接“反向操作”你的原頁面。
就像這樣簡單粗暴的一行:
window.opener.location = 'https://a-new-page.com';
意思就是:
“把原來的那一頁,重定向到我指定的這個新地址。”
這種操作,有個專業(yè)(但聽起來就很陰間)的名字:tabnabbing(標(biāo)簽劫持)。
你以為你只是好心把外鏈丟到新標(biāo)簽頁, 結(jié)果人家順著這條“繩子”,直接把你的原頁面拖走了。
更可怕的是——用戶根本意識不到發(fā)生了什么。
剛才還在你的后臺系統(tǒng)里操作
刷一下,頁面“看起來差不多”,其實(shí)已經(jīng)換了站點(diǎn)
繼續(xù)輸入密碼、填表單、點(diǎn)擊按鈕……
全程沒警覺,你的平臺就這樣被“借殼上演了一場騙局”。
哪些場景尤其危險?
這種“標(biāo)簽劫持”風(fēng)險,對下面這些場景尤其致命:
管理后臺(Admin 面板)
支付系統(tǒng) / 充值頁面
郵箱 / 賬號登錄頁
SaaS 后臺、數(shù)據(jù)控制臺
政府、醫(yī)療、教育等敏感業(yè)務(wù)頁面
只要你的用戶:
在你這個頁面里登錄過
輸入過敏感信息
做過對賬號有影響的操作
那一旦被人利用 window.opener 做文章,你和用戶就一起掉坑里了。
一行就能補(bǔ)上的安全大洞:rel="noopener noreferrer"
好消息是,修這個問題,真的只要 加一小段屬性:
<a target="_blank" rel="noopener noreferrer">更安全的外鏈</a>
就這一行:
rel="noopener noreferrer"
后面這兩個值,分別干這些事:
noopener:直接剪斷那根“控制原頁面”的線
rel="noopener" 的作用是:
告訴瀏覽器: “新開的那一頁,不允許通過
window.opener訪問/控制我。”
也就是說:
新標(biāo)簽頁依然能正常打開
但它不再有權(quán)限反向操作你的原頁面
window.opener變成null,這條路被你堵死了
tabnabbing 這條攻擊鏈,直接被斬斷。
noreferrer:順帶把“我是誰”也隱藏掉
rel="noreferrer" 做的事情是:
在跳轉(zhuǎn)時,不再把“從哪個頁面來的”這個信息, 通過 HTTP Referer 頭部傳給目標(biāo)站點(diǎn)。
簡單說:
對方拿不到你頁面的 URL 作為來源
某些老瀏覽器里,不加這個就沒法同時兼容
noopener也順手給用戶多了一層隱私保護(hù)
兩個屬性一起用,就是現(xiàn)在業(yè)界推薦的“標(biāo)配”:
rel="noopener noreferrer"
它們一起做到了:
不給對方遠(yuǎn)程控制權(quán)
不亂暴露用戶從哪兒來的
還順便補(bǔ)上老瀏覽器的坑
你付出的成本? 不過就是在 <a> 標(biāo)簽里,多敲了 20 來個字符而已。
“瀏覽器不是已經(jīng)幫我自動加 noopener 了嗎?”
確實(shí),部分現(xiàn)代瀏覽器 在某些場景里, 會自動為 target="_blank" 的外鏈加上 noopener。
但問題有兩個:
并不是所有瀏覽器都這么做
你也不能保證將來改動、第三方組件、特殊環(huán)境里不會漏掉
作為一個開發(fā)者, 在這種“成本極低、收益極大”的地方, 與其賭瀏覽器,不如自己寫死。
親手多寫 1 行, 好過哪天追著用戶說:“這個問題是瀏覽器的問題,不是我。”
什么時候該用?什么時候不必用?
這對組合,也不是“逢 <a> 必加”。
可以簡單記住一條:
給“外鏈”加上它
指向你無法完全信任的站點(diǎn)
跳到第三方支付、第三方內(nèi)容平臺
跳到合作方、廣告方、外部工具
這些地方,一律建議:
<a target="_blank" rel="noopener noreferrer">第三方頁面</a>
內(nèi)部導(dǎo)航,正常情況下不用加
如果你的鏈接是:
同一域名下的頁面之間跳轉(zhuǎn)
同一 SPA 應(yīng)用內(nèi)部用
<a>做路由(而不是window.open)必須依賴
window.opener做明確的、可信的雙向通信
那就不必強(qiáng)行加 noopener。 在同一個受控環(huán)境下,相互通信本身就是設(shè)計的一部分。
但有一點(diǎn)可以堅守:
只要是 “點(diǎn)了就跳出我控制范圍” 的鏈接, 我都會習(xí)慣性補(bǔ)上這兩個屬性。
順手一個小優(yōu)化:用 CSS 標(biāo)記所有“會開新標(biāo)簽的外鏈”
為了給用戶一點(diǎn)“視覺提示”, 我還習(xí)慣順帶加一點(diǎn)點(diǎn) CSS:
a[target="_blank"] {
cursor: pointer;
}
a[target="_blank"]::after {
content: "↗";
font-size: 0.8em;
margin-left: 0.25em;
}這樣用戶一眼就能看出來:
這個鏈接點(diǎn)了會開新標(biāo)簽
跳出當(dāng)前站點(diǎn),不是普通內(nèi)部導(dǎo)航
UX 更清晰,安全感也更足一點(diǎn)。
最后一句:真正“專業(yè)”的前端,很多時候就藏在這種小細(xì)節(jié)里
rel="noopener noreferrer" 看起來只是一個不起眼的小屬性。
頁面不加照樣能跑
一般用戶也察覺不到區(qū)別
控制臺也不會給你報紅
可它解決的是一個:
“安安靜靜存在了很多年,但一旦被利用就很致命”的問題。
你多寫這一行:
用戶更安全
你的站更難被拿去當(dāng)“跳板”或釣魚工具
安全審計時看你的代碼,也會多一絲尊重
成本幾乎為零,收益卻相當(dāng)可觀。
所以,下次你再寫:
<a target="_blank">外鏈</a>
不妨養(yǎng)成一個小習(xí)慣,順手補(bǔ)上這一段:
rel="noopener noreferrer"
就這一行, 讓外鏈安全了一大截。
鏈接類型處理表格
| 鏈接類型 | target | rel屬性 | 說明 |
|---|---|---|---|
| 內(nèi)部鏈接 | 不設(shè)置或_self | (無需) | 站內(nèi)導(dǎo)航 |
| 內(nèi)部資源 | _blank | noopener | PDF、下載文件等 |
| 可信外部 | _blank | noopener noreferrer | 合作伙伴、參考資料 |
| 用戶內(nèi)容 | _blank | ugc nofollow noopener noreferrer | 評論、論壇帖子 |
| 廣告鏈接 | _blank | sponsored nofollow noopener noreferrer | 付費(fèi)廣告、推廣 |
| 社交媒體 | _blank | noopener noreferrer | 分享按鈕 |
| 登錄/注冊 | _blank | noopener noreferrer | OAuth認(rèn)證等 |
總結(jié)
到此這篇關(guān)于使用noopener和noreferrer讓HTML中的外部鏈接更安全的文章就介紹到這了,更多相關(guān)noopener和noreferrer讓HTML外鏈更安全內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深度學(xué)習(xí)開源框架基礎(chǔ)算法之傅立葉變換的概要介紹
今天小編就為大家分享一篇關(guān)于深度學(xué)習(xí)開源框架基礎(chǔ)算法之傅立葉變換的概要介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
select下拉菜單實(shí)現(xiàn)二級聯(lián)動效果
這篇文章主要介紹了select下拉菜單實(shí)現(xiàn)二級聯(lián)動效果,在一些項目開發(fā)中經(jīng)常會遇到這樣的需求,今天小編通過實(shí)例代碼給大家講解,需要的朋友可以參考下2019-10-10
用VSCode實(shí)現(xiàn)內(nèi)網(wǎng)穿透的步驟詳解
這篇文章給大家介紹了如何用VSCode實(shí)現(xiàn)內(nèi)網(wǎng)穿透,文中通過圖文結(jié)合的方式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12
vscode+picgo+github配置免費(fèi)圖床(圖文教程)
本文主要介紹了vscode+picgo+github配置免費(fèi)圖床,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01

