Binance API Key .env 外洩:webhook 為什麼突然 401
Alert 設好了,圖表上條件明明滿足,結果webhook 回傳 401——你確定 key 沒改過、IP 白名單也沒動。唯一變化的,是你最近把 bot 從測試環境搬到生產環境,並且「順便」在專案根目錄建了一個 .env。
問題不在於「有無使用 .env」——幾乎所有嚴謹的 bot 都靠它載入機密。問題在於:你讓誰、在什麼時間點、透過什麼管道,讀到了那串 key。
.env 的作法本身沒錯,但「環境變數被讀取到日誌、Git history、process list」才是真正的外洩路徑。這一篇用實際案例拆解 Binance API Key 外洩 .env 的典型場景,並給出能立刻檢查的防呆清單。以下分四層說明:
1. Binance API Key 外洩 .env 的典型場景:從「看起來很安全」到「突然被 BAN IP」的常見失誤點 2. 如何判斷你的 key 是否已經被盜用:API 活動日誌與異常交易模式 3. 為什麼 webhook 會回傳 401:除了 key 錯,還有什麼會導致 Binance 拒絕請求 4. 防呆檢查清單:能立刻執行、但能救命的操作步驟
Binance API Key 外洩 .env 的典型場景
從日誌裡漏出來的 key
這是最容易忽略的。某些 logger 框架在 debug 模式下會把整個 process.env 物件印出來——尤其是開發階段忘了關 debug 的時候。以 winston 為例,若 inspectOptions 包含 depth: null 或 showHidden: true,且程式碼明確將 process.env 放入 log message 的序列化流程,就會把 BINANCE_API_KEY=xxx... 完整吐到日誌檔案裡。
// winston config 若設了 depth: null,會印出所有 env
const logger = require('winston').createLogger({
format: combine(
errors({ stack: true }),
printf(info => {
// debug 模式下可能展開 process.env
return info.level + ': ' + JSON.stringify(info.message, null, 2);
})
)
});檢查方式:用 grep 搜尋過去一週的日誌,看有沒有出現類似 BINANCE_、API_KEY 的字串。
grep -i "BINANCE\|API_KEY" ~/Library/Logs/bot.log | head -20如果看到長串字母數字組合,立即撤換 key。Binance 的 Secret Key 在建立之後就不可恢復——官方 FAQ 明寫:「Secret Keys are only visible at the time the API Key is created. Any time after that point, it will be masked. If you have lost it, or you did not record it, you will need to create a new API Key and use a new Secret Key」(來源:Binance API FAQ)。
Git history 藏著機密
你以為已經 git rm --cached .env、.env 加入 gitignore,但實際上:
- .env.example 或 .env.template 裡可能寫了「範例 key」(有人會把真實 key 當範例) - CI/CD pipeline 的 log 把 .env 的內容印出來 - Dockerfile 的 ENV 指令被 commit 進去
檢查方式:用 git log -p --all | grep -i "BINANCE\\|API_KEY" 搜尋歷史。
process list 洩漏機密
在 Linux/macOS,ps aux | grep node 會顯示所有 running process 的 command line。如果你啟動 bot 時帶了 -e BINANCE_API_KEY=xxx,這串 key 就永遠暴露在系統中。
# ❌ 危險:key 出現在 ps 輸出
node -e "BINANCE_API_KEY=xxx" app.js
ps aux | grep node # ← 這裡會印出 xxx正確做法:用 .env 載入,不要 inline。
# ✅ 安全:key 只在 .env 檔案內
source .env && node app.js遠端主機 / VPS 的 SSH session 洩漏
如果你用 scp、rsync、或某些自動化腳本把 .env 傳到遠端機器,而遠端機器本身沒有 .gitignore、沒有 log rotation,key 可能:
- 出現在 /var/log/auth.log 的 ssh session info - 被其他工具(如 Ansible)印出來 - 透過 SFTP 的 debug log 洩漏
檢查方式:在遠端主機搜尋 .env 檔案。
find /tmp /var /home -name ".env" -o -name "*.env*" 2>/dev/null如何判斷你的 key 是否已經被盜用
檢查 Binance API 活動日誌
Binance API Management 頁面(api management)會記錄每把 key 的最近活動時間、IP 來源和請求統計。如果你看到:
- 陌生的 IP 位址:白名單內只有你的 VPS,但日誌出現其他國家的連線 - 非你操作的時段有請求:凌晨三點大量 API 呼叫,但你當時沒在跑 bot - 請求頻率異常高:正常每天幾百次,突然變成幾萬次
以上任一情況,都應該假設 key 已經外洩。
檢查帳戶是否有異常交易
如果攻擊者拿到了你的 可下單 key(不只是只讀),他們可能會:
- 用你的資金做高頻交易,消耗手續費 - 將資產轉移到其他地址 - 利用你的 API 額度進行市場操縱
檢查方式:到 Binance 的「訂單歷史」和「資金歷史」頁面,比對每一筆交易是否為你所為。如果發現不明交易,立即撤換所有 key 並聯繫 Binance 客服。Binance 官方建議:「If you notice unusual activity in your account, immediately revoke all the keys and contact Binance support」(來源:Binance Request Security)。
為什麼 webhook 會回傳 401
Binance API 驗證失敗的常見原因
Binance REST API 的驗證失敗通常回傳 JSON body 中的 -2015(金鑰無效、IP 不在白名單或沒有權限)或 -1022(INVALID_SIGNATURE,簽章錯誤);請求太多被限流則是 -1003(TOO_MANY_REQUESTS),HTTP 狀態碼則是 4XX。Binance 官方文件並未將錯誤訊息寫成「HTTP 401 Invalid Api-Key ID」——它是一個包含 code: -1022 的 JSON payload。
| 原因 | 特徵 | 解決 |
|---|---|---|
| IP 白名單限制 | 從新 IP 連線就失敗 | 在 Binance API Management 新增當前 IP |
| Key 被撤銷或停用 | 所有請求都回 -2015 | 重新生成 Key,更新 .env |
| 權限不足 | 某些端點(如 account)需要 TRADE 權限 | 檢查 API 權限設定 |
| Signature 錯誤 | -1022 INVALID_SIGNATURE | 檢查 timestamp、nonce、signature 生成邏輯 |
| Rate limit 觸發 | HTTP 429 | 加入退避(backoff)機制,Binance 硬限為 6,000 req weight/min |
Binance API 驗證失敗常見原因 — 查證來源:developers.binance.com/docs/binance-spot-api-docs/rest-api/rate-limits
TradingView webhook 的常見陷阱
TradingView 本身的限制也會導致「看起來像 401」——因為請求根本沒到達 Binance:
- 3 秒 timeout:TradingView 官方文件明確寫道:「If a remote server takes longer than three seconds to process a request, the request will be cancelled」(來源:TradingView Help Center)。如果你的 bot 同步呼叫 Binance API,超過 3 秒就回傳,webhook 直接失敗。 - JSON body 格式錯誤:某些字段(如 symbol)需要符合 Binance 的規範(例如 BTCUSDT 而不是 btc/usdt)。Binance 對無效 symbol 回傳 -1121 Invalid symbol。 - TLS/SSL 問題:如果你的 webhook endpoint 使用自簽證書,Binance 可能會拒絕連線。
如何判斷是 Binance 的問題還是你的 bot 的問題
快速檢查流程:
1. 用 curl 直接測試 API:
# 讀取 .env 中的 key
source .env
# 發送測試請求
curl -s -v -H "X-MBX-APIKEY: $BINANCE_API_KEY" -X POST "https://api.binance.com/api/v3/orderTest" --data-urlencode "symbol=BTCUSDT" --data-urlencode "side=BUY" --data-urlencode "type=MARKET" --data-urlencode "quantity=0.001" --data-urlencode "timestamp=$(date +%s)000" --data-urlencode "signature=$(openssl dgst -sha256 -hmac "$BINANCE_SECRET_KEY" -hex | awk '{print $2}')" 2>&1 | grep -E "HTTP/|code|msg"如果 curl 也回傳 -2015,問題在 Binance API Key 本身(金鑰、IP 白名單或權限);如果 curl 成功但 webhook 失敗,問題在你的 bot。
2. 檢查 Binance API Management 頁面:Binance 後台(api management)允許查看 API key 設定與 IP 白名單。如果請求量異常,就能快速定位問題。
防呆檢查清單
立即執行
- 撤換所有可能洩漏的 API Key:在 Binance API Management 重新生成,更新 .env
- 搜尋日誌中的機密字串:grep -ri "BINANCE\|API_KEY" ~/Library/Logs/*
- 檢查 Git history:git log -p --all | grep -i "BINANCE"
- 確認 .env 在 .gitignore 中:檢查根目錄的 .gitignore
- 遠端主機搜尋 .env:find /tmp /var /home -name ".env" 2>/dev/null
- 檢查 API Management 的活動日誌:確認沒有異常 IP 或時段
短期改進(1 週內)
- 加入環境變數驗證:啟動時檢查 process.env.BINANCE_API_KEY 是否存在,不存在就 exit
- 使用 .env.example 作為範本:不要寫實際 key,只留欄位名稱
- 設定日誌輪轉:避免日誌無限增長導致硬碟爆滿
- 加入 IP 白名單監控:定期檢查 API Management 的 IP 列表
長期架構(1 個月內)
- 考慮使用 secrets manager:如 AWS Secrets Manager、HashiCorp Vault,或本地解決方案
- 加入 key rotation 機制:定期自動撤換 API Key,減少洩漏風險
- 建立告警系統:當偵測到不正常的 API 請求時,立即通知
常見問題
我已經把 .env 放在 .gitignore 中,為什麼還是會洩漏?
Binance API Key 外洩後,多久會被發現?
我可以用 .env.local 或 .env.production 來區分環境嗎?
如果我的 bot 是 Docker 部署,怎麼避免 key 洩漏?
Dockerfile 中使用 ENV 指令 - 使用 docker run -e BINANCE_API_KEY=xxx(key 只存在 runtime) - 或使用 Docker secrets / volume 載入 .envTradingView webhook 的 401 和 Binance API Key 外洩有什麼關係?
Get started
如果你懷疑 API Key 可能洩漏,請盡快撤換所有 API Key、更新 .env、搜尋日誌和 Git history 中的舊 key,並重新啟動 bot 後持續監控 API 用量。
免費開始使用