Strapi 忘記密碼的安靜回應:Anti-Enumeration、Phishing-as-a-Service 與撞庫經濟學

問題現場:一個「成功」卻收不到信的忘記密碼 某個週一下午,QA 回報:在一個 Flutter + Strapi 架構的 App 上,用測試帳號 testuser@example.com 點「忘記密碼」,畫面跳出 Success: Reset password link sent successfully on your email account.,但信箱(包含垃圾郵件匣)一封信都沒有。 直覺先排除幾個明顯可能:SMTP 設定壞掉、用戶被 block、信件被 Gmail 擋。但真正的答案比這些都有趣 — 這不是 bug,是 Strapi 一個刻意的安全設計,只是 App 前端把它翻譯錯了。 kubectl 診斷:20ms 與 800ms 的兩種人生 進 Strapi pod 撈 log,找 forgot-password 請求: kubectl logs -n default strapi-prod-xxxxxxxxx-xxxxx --since=6h \ | grep -E 'forgot-password|Reset password URL' 抽出的關鍵幾行: 04:04:52 info: Reset password URL generated: https://example.com/... 04:04:53 http: POST /api/auth/forgot-password (948 ms) 200 05:15:44 http: POST /api/auth/forgot-password (20 ms) 200 05:16:53 info: Reset password URL generated: https://example.com/... 05:16:54 http: POST /api/auth/forgot-password (664 ms) 200 05:17:30 http: POST /api/auth/forgot-password (26 ms) 200 一眼看出兩種節奏:800ms 級別的請求伴隨「Reset password URL generated」log,而 20-30ms 的請求則完全沒有。同一支 API,為什麼耗時差 30 倍? ...

April 21, 2026 · 4 分鐘 · Peter

在 Kubernetes 上部署 OV SSL 證書:完整實戰指南

為什麼選擇 TWCA OV 證書 在生產環境中,使用自簽憑證會導致瀏覽器顯示不安全警告,影響使用者信任。雖然 Let’s Encrypt 提供免費的自動化證書,但某些企業或政府專案需要台灣在地的認證機構簽發證書以符合法規要求。 SSL 證書的三個等級 SSL 證書依據驗證強度分為三個等級: 證書類型 驗證內容 適用場景 信任標記 價格 DV (Domain Validation) 僅驗證網域所有權 個人網站、部落格 🔒 基本鎖頭 免費~低 OV (Organization Validation) 驗證組織身份 企業網站、SaaS 服務 🔒 組織名稱 中 EV (Extended Validation) 嚴格驗證企業 金融、電商、政府 🟢 綠色網址列 高 本文使用的是 TWCA OV SSL 證書,它提供: ✅ 組織身份驗證(瀏覽器可顯示公司名稱) ✅ 完整的證書鏈(受所有主流瀏覽器信任) ✅ 12 個月有效期 ✅ 台灣在地技術支援 HTTPS 與 SSL/TLS 運作原理 在深入部署之前,先理解 HTTPS 如何保護資料傳輸: 關鍵機制說明: 非對稱加密(RSA/ECDSA):只用於金鑰交換,確保 session key 安全傳輸 對稱加密(AES):實際資料傳輸使用,效能更好 證書鏈驗證(完全離線):瀏覽器使用內建的 TWCA 根憑證驗證整個證書鏈,不需要連線到 TWCA 中間人攻擊防護:因為攻擊者沒有伺服器的私鑰,無法解密通訊 💡 重要觀念: TWCA 只在簽發證書時參與,TLS 握手過程中完全不涉及。瀏覽器使用內建的根憑證庫(包含 TWCA 根憑證)進行離線驗證。 ...

December 10, 2025 · 6 分鐘 · Peter

解決 Strapi CMS 正式環境空白頁的踩坑經驗分享

前言:一個簡單的環境變數引發的災難 在部署 Strapi CMS 到 Kubernetes 正式環境時,只是加了一行看似無害的環境變數設定: env: - name: NODE_ENV value: production # 就是這一行! 結果卻導致整個管理後台變成一片空白,連登入頁面都看不到。更詭異的是: ✅ API 完全正常,GraphQL 和 REST 都能回應 ✅ Pod 狀態正常,沒有任何錯誤訊息 ✅ 日誌顯示 Strapi 成功啟動 ❌ 瀏覽器打開 /admin 卻是一片空白 這種「Schrodinger 的服務」(同時正常又不正常)讓人抓狂。經過一番排查,終於發現罪魁禍首是 CSP (Content Security Policy) 在作怪。 本文將深入探討: 為什麼正式環境會出現空白頁 CSP 的工作原理與安全機制 完整的問題排查步驟 如何正確配置 Strapi 的安全策略 生產環境的安全最佳實踐 問題背景:開發正常,正式環境空白 環境差異對比 問題現象詳細描述 Kubernetes Deployment 設定: apiVersion: apps/v1 kind: Deployment metadata: name: strapi-prod namespace: default spec: replicas: 1 selector: matchLabels: app: strapi template: metadata: labels: app: strapi spec: containers: - name: strapi image: myregistry.com/strapi:v5.0.0 env: - name: NODE_ENV value: production # 問題的起點 - name: DATABASE_HOST valueFrom: secretKeyRef: name: strapi-db-secret key: host - name: ADMIN_JWT_SECRET valueFrom: secretKeyRef: name: strapi-admin-secret key: jwt-secret ports: - containerPort: 1337 部署後的症狀: ...

May 7, 2025 · 8 分鐘 · Peter