安全使用 target="_blank" 的方式
本文件說明使用 target="_blank"
開啟新分頁時可能面臨的安全風險,並提供完整的解決方案來防止「反向標籤劫持」(Reverse Tabnabbing)攻擊,適合前端開發者了解與實作安全的外部連結。
安全風險說明
什麼是反向標籤劫持攻擊
當使用 target="_blank"
開啟外部連結時,新開啟的頁面會獲得原始頁面的 window.opener
參考,這讓惡意網站有機會操控原始頁面。
攻擊流程:
- 使用者點擊含有
target="_blank"
的連結 - 新分頁開啟後,惡意網站取得
window.opener
物件 - 惡意網站透過
window.opener.location
將原始頁面導向釣魚網站 - 使用者回到原始分頁時,看到的是偽造的釣魚頁面
潛在風險
- 釣魚攻擊:原始頁面被導向看似合法的釣魚網站
- 資料竊取:使用者可能在釣魚網站輸入敏感資訊
- 信任濫用:利用使用者對原始網站的信任進行詐騙
不安全的寫法
以下是容易受到攻擊的常見寫法:
html
<!-- ❌ 危險:僅使用 target="_blank" -->
<a href="https://external-site.com" target="_blank"> 查看外部網站 </a>
<!-- ❌ 危險:JavaScript 開啟新視窗 -->
<button onclick="window.open('https://external-site.com')">開啟外部網站</button>
為什麼不安全:
- 新開啟的頁面可以透過
window.opener
存取原始頁面 - 惡意網站可以執行
window.opener.location = 'https://fake-site.com'
- 原始頁面會在背景被重新導向到惡意網站
安全的解決方案
方案一:使用 rel="noopener"
這是最主要的解決方案,可以阻斷新頁面對原始頁面的存取:
html
<!-- ✅ 安全:使用 rel="noopener" -->
<a href="https://external-site.com" target="_blank" rel="noopener">
查看外部網站
</a>
<!-- ✅ 更安全:同時使用 noopener 和 noreferrer -->
<a href="https://external-site.com" target="_blank" rel="noopener noreferrer">
查看外部網站
</a>
屬性說明:
rel="noopener"
:防止新頁面存取window.opener
rel="noreferrer"
:不傳送 HTTP Referer 標頭,增加隱私保護
方案二:JavaScript 安全開啟新視窗
當需要用 JavaScript 開啟新視窗時,確保清除 opener
參考:
javascript
// ✅ 安全的 JavaScript 寫法
function openSafeWindow(url) {
const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
// 額外保護:手動清除 opener 參考
if (newWindow) {
newWindow.opener = null
}
}
// 使用範例
document
.getElementById('external-link')
.addEventListener('click', function (e) {
e.preventDefault()
openSafeWindow('https://external-site.com')
})
注意事項
- 使用
rel="noreferrer"
會阻止瀏覽器傳送 HTTP Referer,外部網站無法得知流量來源,可能影響 SEO 分析與流量統計。 - 若希望保留 Referer 以利 SEO 分析,僅使用
rel="noopener"
即可,避免加上noreferrer
。 - 針對重要外部連結,建議根據實際需求選擇是否加上
noreferrer
。
參考資料
MDN - rel="noopener"MDN - rel="noreferrer"OWASP - Reverse TabnabbingGoogle Web Fundamentals - External linksCan I use - rel=noopener