資安指南

安全超入門:.env 和 API key 到底危險在哪、又該怎麼守

寫給個人開發者的第一步:.env 是什麼、API key 外洩後會發生什麼(別人以你的身分使用服務,帳單算你的),以及今天就能做的 4 個基本防護:不公開、不提交、外洩就全部更換、定期自查。

發布於 2026-06-07 更新於 2026-10-06 閱讀時間 3 分鐘
本頁內容

「都說安全很重要,可到底該先從哪兒下手?」——這就是寫給這樣的個人開發者的、最最開始的第一步。不是為了嚇唬你,而是只把從今天就能動手的事,按順序講清楚。

為什麼要從秘密的值(.env 和 API key)開始

真實發生的事故,很多都不是什麼高級攻擊,而是從**「秘密的值洩漏了」**開始的。本站拿來作為出發點的兩個案例,也都是秘密洩漏:

也就是說,只要能守住秘密的值,常見事故裡的絕大多數就都能防住。所以我們就從這裡開始。

.env 是什麼(30 秒講完)

.env(點 env)是把應用程式要用的秘密的值彙總到一起的設定檔。裡面裝著資料庫的密碼、外部服務的 API key、給工作階段加密用的金鑰等等。正因為秘密都集中在一個檔案裡,一旦洩漏就會一口氣全部外洩,所以要最優先地守好它(→ 術語:.env 是什麼)。

秘密的值可以放在哪裡(.env、環境變數、秘密管理服務)

.env 並不是放秘密的唯一地方。請依規模和用途選擇。

位置適合要注意的地方
.env 檔本機開發、單台小型伺服器排除在 Git 之外,也不要放進公開目錄
主機的環境變數設定(在管理介面輸入)正式環境限制能存取管理介面的人;別讓值出現在建置日誌裡
CI(自動測試與部署)的 secretsGitHub Actions 等自動化在 CI 中執行的外部工具看得到這些值;只傳入具備必要權限的 key
秘密管理服務多人或多台伺服器讀取權限保持最小,並定期輪換

關於 CI 的 secrets,2021 年的 Codecov 事件是很好的參考。在 CI 中執行的外部工具遭到竄改,存放在 CI 環境變數中的秘密被拿走了(→ Codecov 事件)。

可以公開的 key 和不能公開的 key

有些 API key 本來就是要放在瀏覽器或行動 App 裡的,有些則只能用在伺服器上。送到瀏覽器的任何東西,都要假設任何人都讀得到。

例子可以公開嗎?理由
Stripe 可公開金鑰(以 pk_ 開頭)可以文件說明可以放在前端程式碼中;它無法進行建立付款這類敏感操作
Stripe 秘密金鑰(sk_)或受限金鑰(rk_)不行能進行伺服器端的操作;文件建議使用縮小權限的受限金鑰
Next.js 中帶 NEXT_PUBLIC_ 的環境變數會被公開它的值會在建置時被內嵌到瀏覽器的 JavaScript
Next.js 中不帶 NEXT_PUBLIC_ 的環境變數不會公開(只在伺服器)秘密的值放這裡

拿不準時,請查看該服務的官方文件,確認這個 key 能不能在用戶端使用。如果文件沒寫,就當作不能公開的 key 處理。

API key 洩漏後會發生什麼

API key 是「讓外部服務把呼叫者當成你的一串字串」。它一旦落到別人手裡,損害會這樣擴大。

① API key 洩漏(經由公開目錄 · git 提交 · 漏洞)
↓ 時間差(數天起)
② 第三方「以你的身分」使用外部服務
↓
③ 盜刷(大量呼叫)/讀寫資料/冒名頂替
洩漏剛發生時悄無聲息。被人有時間差地濫用,某一天帳單或損失突然浮出水面。

被偷走的 key 往往會有時間差地被轉賣、濫用,「洩漏剛發生時啥也沒有→過些天帳單突然飆升」是很典型的套路。所以「等發現了再說」就晚了,關鍵是從一開始就別讓它洩漏。

key 可能已經洩漏時該怎麼做

把 key 從程式碼裡刪掉,並不能讓它失效。GitGuardian 2025 年的報告發現,2022 年在公開儲存庫中外洩的秘密,有 70% 到報告發布時仍然有效。請按以下順序處理。

  1. 在發行方的管理介面撤銷或輪換這個 key。如果服務提供寬限期,請讓外洩的 key「立即」失效
  2. 在正式環境設定新的 key,並確認應用程式正常運作
  3. 查看發行方的使用紀錄和帳單,確認有沒有不是你做的活動
  4. 從檔案和 Git 歷史中移除可以等撤銷之後再做(光是刪除,擋不住已經拿到副本的人)

詳情請見 在 GitHub 上公開的 54 萬組憑證仍然有效。GitHub 預設開啟「push protection」,會阻止個人帳號把秘密推送到公開儲存庫,但它並不能抓到所有種類的秘密。

從今天就能做的 4 個防護辦法

不需要什麼難的東西。先做好這 4 件就行。

1

不公開

別把 .env 和應用程式本體放到 Web 上能看見的目錄(公開根目錄)裡。對外公開的只能是 public/。在虛擬主機上的具體操作步驟見 這篇文章。

2

不提交

在 .gitignore 裡加上 .env*(!.env.example 可以放行)。只共享不帶值的範例。一旦提交過就能從歷史裡還原出來,所以從一開始就別放進去。

3

洩漏就全部更換

不是只換一個,而是把有可能洩漏的鑰匙全部輪換。優先順序是「外部 API · OAuth → 加密金鑰 → 郵件 → DB」。按「已經被看到了」的前提來處理。

4

自查

偶爾確認一下自己的網站,看 /.env 能不能從外面打開(見下)。

自查(只對自己擁有的網域做)

# 回傳 200 且帶正文就是被公開了。403/404 則暫時沒問題
curl -sI https://你的網域/.env | head -1
curl -sI https://你的網域/.git/config | head -1

養成每次上線都確認一遍的習慣,就能盡早發現放置位置的失誤。

除了從外部看得到的部分,也請檢查 Git 和建置產物(在你自己的儲存庫中執行)。

# .env 是否曾經被提交過?(只要有輸出,就代表某個時間點提交過)
git log --all --oneline -- .env
# Git 目前追蹤的 env 類檔案(.env.example 以外的都要確認)
git ls-files | grep -i "env"

要確認沒有 key 被送到瀏覽器,請在建置輸出資料夾(Next.js 是 .next/static)中搜尋 key 的前幾個字元。也可以在公開前把程式碼貼到 機密外洩掃描 檢查(不會傳送到任何地方)。

容易犯的錯 vs 正確的第一步

容易犯

  • 反正先跑起來了,就把 .env 直接放在 public 下
  • 想著「以後再刪」,把 .env 提交進 git 一次
  • 只換那一個看到被濫用的鑰匙

正確的第一步

  • 本體放在公開根目錄之外,只公開 public/
  • 從一開始就用 .gitignore 把 .env 排除掉
  • 洩漏了就把 env 裡的鑰匙全部輪換

下一步

走到這一步,接下來就是「自己技術棧裡危險的預設設定」和「不在已公開漏洞(CVE)上落後的機制」了。別著急,一個一個來。

出處

接著讀

FAQ

Q想學安全,該從哪兒開始?
A

先從『不讓秘密的值(.env 和 API key)洩漏出去』開始。很多真實事故都是從這裡發生的。不公開、不提交到 git、洩漏就全部更換、偶爾自查一下,做好這 4 點就能擋住絕大多數事故。

QAPI key 洩漏後,具體會發生什麼?
A

別人能冒充你去使用外部服務。常見的就是盜刷(用你的帳單跑大量呼叫),以及讀寫資料。洩漏的 key 往往會有時間差地被轉賣、濫用。

Q.env 可以放進 git 嗎?
A

不可以。要在 .gitignore 裡加上 .env*,只共享把值清空後的 .env.example。一旦提交過,即便之後刪掉,也能從 git 的歷史裡還原出來。

Q.env 檔是什麼?
A

一種把應用程式的設定,尤其是密碼和 API key 這類秘密的值,和程式碼分開保存的文字檔。每一行的格式是 名稱=值。Laravel、Next.js、Django 等許多框架都會在啟動時讀取它。正因為秘密都集中在這裡,它必須排除在 Git 之外,也不能放進公開目錄。

Q.env 和環境變數有什麼不同?
A

環境變數是機制本身:由作業系統或執行環境傳給程式的值。.env 檔則是把這些值寫在檔案裡的容器,讓應用程式或函式庫在啟動時把它們載入成環境變數。在正式環境中,許多做法會略過 .env 檔,改從主機的管理介面或秘密管理服務傳入環境變數。

Q可以把 API key 放在前端(瀏覽器)的程式碼裡嗎?
A

只有官方明確說明可以公開的 key 才行。送到瀏覽器的 JavaScript 任何人都讀得到。例如 Stripe 的文件說明,可公開金鑰(以 pk_ 開頭)可以放在前端程式碼中,但秘密金鑰(sk_)和受限金鑰(rk_)絕不能暴露。在 Next.js 中,以 NEXT_PUBLIC_ 開頭的環境變數會被內嵌到瀏覽器的程式碼裡,所以絕不要給秘密的值加上這個前綴。