「都說安全很重要,可到底該先從哪兒下手?」——這就是寫給這樣的個人開發者的、最最開始的第一步。不是為了嚇唬你,而是只把從今天就能動手的事,按順序講清楚。
為什麼要從「秘密的值」開始
真實發生的事故,很多都不是什麼高級攻擊,而是從**「秘密的值洩漏了」**開始的。本站拿來作為出發點的兩個案例,也都是秘密洩漏:
也就是說,只要能守住秘密的值,常見事故裡的絕大多數就都能防住。所以我們就從這裡開始。
.env 是什麼(30 秒講完)
.env(點 env)是把應用程式要用的秘密的值彙總到一起的設定檔。裡面裝著資料庫的密碼、外部服務的 API key、給工作階段加密用的金鑰等等。正因為鑰匙都集中在一個檔案裡,一旦洩漏就會一口氣全部洩漏,所以要最優先地守好它(→ 術語:.env 是什麼)。
API key 洩漏後會發生什麼
API key 是「以你的身分去使用外部服務的、配出來的一把鑰匙」。它一旦落到別人手裡,就會這樣連鎖下去。
被偷走的 key 往往會有時間差地被轉賣、濫用,「洩漏剛發生時啥也沒有→過些天帳單突然飆升」是很典型的套路。所以「等發現了再說」就晚了,關鍵是從一開始就別讓它洩漏。
從今天就能做的 4 個防護辦法
不需要什麼難的東西。先做好這 4 件就行。
不公開
別把 .env 和應用程式本體放到 Web 上能看見的目錄(公開根目錄)裡。對外公開的只能是 public/。在虛擬主機上的具體操作步驟見 這篇文章。
不提交
在 .gitignore 裡加上 .env*(!.env.example 可以放行)。只共享不帶值的範例。一旦提交過就能從歷史裡還原出來,所以從一開始就別放進去。
洩漏就全部更換
不是只換一個,而是把有可能洩漏的鑰匙全部輪換。優先順序是「外部 API · OAuth → 加密金鑰 → 郵件 → DB」。按「已經被看到了」的前提來處理。
自查
偶爾確認一下自己的網站,看 /.env 能不能從外面打開(見下)。
自查(只對自己擁有的網域做)
# 回傳 200 且帶正文就是被公開了。403/404 則暫時沒問題
curl -sI https://你的網域/.env | head -1
curl -sI https://你的網域/.git/config | head -1養成每次上線都確認一遍的習慣,就能盡早發現放置位置的失誤。
容易犯的錯 vs 正確的第一步
容易犯
- 反正先跑起來了,就把
.env直接放在 public 下 - 想著「以後再刪」,把
.env提交進 git 一次 - 只換那一個看到被濫用的鑰匙
正確的第一步
- 本體放在公開根目錄之外,只公開
public/ - 從一開始就用
.gitignore把.env排除掉 - 洩漏了就把 env 裡的鑰匙全部輪換
下一步
走到這一步,接下來就是「自己技術棧裡危險的預設設定」和「不在已公開漏洞(CVE)上落後的機制」了。別著急,一個一個來。
接著讀
- 術語:.env 是什麼 / CVE 是什麼 / RCE 是什麼
- 防護:在虛擬主機上別讓 .env 被公開 / Next.js 的 CVE 跟進
- 事故:API key 被偷走後遭盜刷的事
- 事故:用偷來的 key 導致帳號被封的事
FAQ
Q想學安全,該從哪兒開始?
先從『不讓秘密的值(.env 和 API key)洩漏出去』開始。很多真實事故都是從這裡發生的。不公開、不提交到 git、洩漏就全部更換、偶爾自查一下,做好這 4 點就能擋住絕大多數事故。
QAPI key 洩漏後,具體會發生什麼?
別人能冒充你去使用外部服務。常見的就是盜刷(用你的帳單跑大量呼叫),以及讀寫資料。洩漏的 key 往往會有時間差地被轉賣、濫用。
Q.env 可以放進 git 嗎?
不可以。要在 .gitignore 裡加上 .env*,只共享把值清空後的 .env.example。一旦提交過,即便之後刪掉,也能從 git 的歷史裡還原出來。