Golang 的安全最佳實務與漏洞防範。涵蓋注入(SQL、命令、XSS)、密碼學、檔案系統安全、網路安全、Cookie、機密管理、記憶體安全與日誌記錄。適用於撰寫、審查或稽核 Go 程式碼的安全性,或處理任何涉及密碼學、I/O、機密管理、使用者輸入處理或身分驗證的高風險程式碼。包含安全工具的設定。
角色設定: 你是一位資深 Go 安全工程師。無論是稽核現有程式碼還是撰寫新程式碼,都要運用安全思維——威脅在預防階段處理遠比事後修補容易。
思考模式: 進行安全稽核與漏洞分析時使用 ultrathink。安全漏洞常隱藏在微妙的互動中——深度推理能捕捉表面審查遺漏的問題。
模式:
- 審查模式 — 審查 PR 中的安全問題。從變更的檔案開始,追蹤呼叫點與資料流進入相鄰程式碼——漏洞可能位於 diff 之外但由 diff 觸發。循序進行。
- 稽核模式 — 完整程式碼庫安全掃描。最多啟動 5 個平行子代理(透過 Agent 工具),每個負責一個獨立的漏洞領域:(1) 注入模式、(2) 密碼學與機密、(3) 網頁安全與標頭、(4) 身分驗證與授權、(5) 並行安全與相依性漏洞。彙整發現結果,以 DREAD 評分,並依嚴重性回報。
- 編碼模式 — 撰寫新程式碼或修復已回報的漏洞時使用。遵循技能的循序指引。可選擇在背景啟動代理,對新撰寫的程式碼 grep 常見漏洞模式,同時主代理繼續實作功能。
相依性:
- govulncheck:
go install golang.org/x/vuln/cmd/govulncheck@latest
Go 安全
概述
Go 的安全性遵循縱深防禦原則:在多層次進行防護,驗證所有輸入,使用安全預設值,並善用標準函式庫的安全意識設計。Go 的型別系統與並行模型提供了一些內建保護,但仍需保持警覺。
安全思考模型
在撰寫或審查程式碼之前,先問三個問題:
- 信任邊界在哪裡? — 不受信任的資料從何處進入系統?(HTTP 請求、檔案上傳、環境變數、其他服務寫入的資料庫行)
- 攻擊者能控制什麼? — 哪些輸入流入敏感操作?(SQL 查詢、Shell 命令、HTML 輸出、檔案路徑、密碼學操作)
- 爆炸半徑有多大? — 如果這道防線失效,最壞的結果是什麼?(資料外洩、RCE、權限提升、阻斷服務)
嚴重性等級
| 等級 | DREAD | 意義 |
|---|---|---|
| 嚴重 | 8-10 | RCE、完整資料外洩、憑證竊取 — 立即修復 |
| 高 | 6-7.9 | 身分驗證繞過、重大資料暴露、加密破損 — 在當前衝刺修復 |
| 中 | 4-5.9 | 有限暴露、Session 問題、防禦弱化 — 在下個衝刺修復 |
| 低 | 1-3.9 | 輕微資訊揭露、偏離最佳實務 — 有機會時修復 |
等級與 DREAD 評分 對齊。
回報前的研究
在標記安全問題之前,請追蹤完整的資料流——不要孤立地評估程式碼片段。
- 追蹤資料來源 — 沿著變數回溯到它進入系統的位置。它是使用者輸入、硬編碼常數,還是僅限內部的值?
- 檢查上游驗證 — 在呼叫鏈中較早的位置尋找輸入驗證、清理、型別解析或允許清單。
- 檢查信任邊界 — 如果資料從未跨越信任邊界(例如,內部服務間使用 mTLS),風險概況會有所不同。
- 閱讀周圍的程式碼,而不只是 diff — 中介軟體、攔截器或包裝函式可能已經提供了一層防禦。
嚴重性調整,而非忽略: 上游防護並不能消除發現——縱深防禦意味著每一層都應保護自己。但它會改變嚴重性:僅能透過嚴格的輸入解析器觸發的 SQL 字串拼接屬於中等,而非嚴重。始終以調整後的嚴重性回報發現,並註明存在哪些上游防禦,以及如果它們被移除或繞過會發生什麼。
當降級或跳過發現時: 加入簡短的內聯註解(例如 // security: SQL concat safe here — input is validated by parseUserID() which returns int),以便決策被記錄、可審查,且不會在未來的稽核中被重新標記。
威脅建模 (STRIDE)
對系統中的每個信任邊界跨越與資料流應用 STRIDE:Spoofing(身分偽造)、Tampering(篡改)、Repudiation(否認)、Information Disclosure(資訊揭露)、Denial of Service(阻斷服務)、Elevation of Privilege(權限提升)。使用 DREAD(Damage 損害、Reproducibility 再現性、Exploitability 可利用性、Affected users 受影響使用者、Discoverability 可發現性)對每個威脅評分,以確定修復優先順序——嚴重(8-10)需要立即行動。
有關完整的 Go 範例方法論、DFD 信任邊界、DREAD 評分與 OWASP Top 10 對應,請參閱 威脅建模指南。
快速參考
| 嚴重性 | 漏洞 | 防禦方式 | 標準函式庫解決方案 |
|---|---|---|---|
| 嚴重 | SQL 注入 | 參數化查詢將資料與程式碼分離 | database/sql 搭配 ? 佔位符 |
| 嚴重 | 命令注入 | 分別傳遞引數,絕不透過 Shell 拼接 | exec.Command 搭配分開的引數 |
| 高 | XSS | 自動跳脫將使用者資料呈現為文字,而非 HTML/JS | html/template、text/template |
| 高 | 路徑遍歷 | 將不受信任的檔案存取限制在允許的根目錄 | Go 1.24+:使用 os.Root。Go 1.24 之前:使用 filepath.IsLocal + filepath.Rel + 分隔符號感知檢查;絕不單獨依賴 filepath.Clean + strings.HasPrefix。 |
| 中 | 計時攻擊 | 常數時間比較避免逐位元組洩漏 | crypto/subtle.ConstantTimeCompare |
| 高 | 密碼學問題 | 使用經過驗證的演算法;絕不自行實作 | crypto/aes、crypto/rand |
| 中 | HTTP 安全 | TLS + 安全標頭防止降級攻擊 | net/http,設定 TLSConfig |
| 低 | 缺少標頭 | HSTS、CSP、X-Frame-Options 防止瀏覽器攻擊 | 安全標頭中介軟體 |
| 中 | 速率限制 | 速率限制防止暴力破解與資源耗盡 | golang.org/x/time/rate、伺服器逾時 |
| 高 | 競爭條件 | 保護共享狀態以防止資料損毀 | sync.Mutex、channel、避免共享狀態 |
詳細分類
完整的範例、程式碼片段與 CWE 對應,請參閱:
- 密碼學 — 演算法、金鑰推導、TLS 設定。
- 注入漏洞 — SQL、命令、模板注入、XSS、SSRF。
- 檔案系統安全 — 路徑遍歷、Zip 炸彈、檔案權限、符號連結。
- 網路/網頁安全 — SSRF、開放重定向、HTTP 標頭、計時攻擊、Session 固定。
- Cookie 安全 — Secure、HttpOnly、SameSite 標誌。
- 第三方資料外洩 — 分析隱私風險、GDPR/CCPA 合規。
- 記憶體安全 — 整數溢位、記憶體別名、
unsafe使用。 - 機密管理 — 硬編碼憑證、環境變數、機密管理工具。
- 日誌安全 — 日誌中的 PII、日誌注入、清理。
- 威脅建模指南 — STRIDE、DREAD 評分、信任邊界、OWASP Top 10。
- 安全架構 — 縱深防禦、零信任、身分驗證模式、速率限制、反模式。
程式碼審查檢查清單
按領域(輸入處理、資料庫、密碼學、網頁、身分驗證、錯誤、相依性、並行)組織的完整安全審查檢查清單,請參閱 安全審查檢查清單 — 一份涵蓋所有主要漏洞類別的程式碼審查綜合檢查清單。
工具與驗證
靜態分析與 Linting
安全相關的 linter:bodyclose、sqlclosecheck、nilerr、errcheck、govet、staticcheck。請參閱 samber/cc-skills-golang@golang-lint 技能以了解設定與使用方式。
針對更深層的安全特定分析:
# Go 安全檢查器 (SAST)
go get -tool github.com/securego/gosec/v2/cmd/gosec@latest
go tool gosec ./...
# 漏洞掃描器 — 完整 govulncheck 使用方式請參閱 golang-dependency-management
go get -tool golang.org/x/vuln/cmd/govulncheck@latest
go tool govulncheck ./...
若要檢查特定模組或版本的已知 CVE,而不掃描整個樹狀結構(例如在 pkg.go.dev 上審查相依性時),→ 請參閱 samber/cc-skills-golang@golang-pkg-go-dev 技能。
安全測試
# 競爭檢測器
go test -race ./...
# Fuzz 測試
go test -fuzz=Fuzz
常見錯誤
| 嚴重性 | 錯誤 | 修正方式 |
|---|---|---|
| 高 | 使用 math/rand 產生 Token |
輸出是可預測的——攻擊者可以重現序列。請使用 crypto/rand |
| 嚴重 | SQL 字串拼接 | 攻擊者可以修改查詢邏輯。參數化查詢將資料與程式碼分離 |
| 嚴重 | exec.Command("bash -c") |
Shell 會解譯特殊字元(;、|、`)。分別傳遞引數以避免 Shell 解析 |
| 高 | 信任未清理的輸入 | 在信任邊界進行驗證——內部程式碼信任邊界,因此在該處攔截不良輸入可保護一切 |
| 嚴重 | 硬編碼機密 | 原始碼中的機密會出現在版本歷史、CI 日誌與備份中。請使用環境變數或機密管理工具 |
| 中 | 使用 == 比較機密 |
== 在第一個不同位元組處短路,洩漏計時資訊。請使用 crypto/subtle.ConstantTimeCompare |
| 中 | 回傳詳細錯誤 | 堆疊追蹤與資料庫錯誤有助於攻擊者繪製系統地圖。回傳通用訊息,詳細資訊記錄在伺服器端 |
| 高 | 忽略 -race 發現 |
競爭會導致資料損毀,並可能在並行情況下繞過授權檢查。修復所有競爭 |
| 高 | 使用 MD5/SHA1 處理密碼 | 兩者都有已知的碰撞攻擊,且暴力破解速度快。請使用 Argon2id 或 bcrypt(刻意慢速、記憶體密集型) |
| 高 | 使用 AES 但不使用 GCM | ECB/CBC 模式缺乏身分驗證——攻擊者可以修改密文而不被發現。GCM 提供加密+身分驗證 |
| 中 | 綁定到 0.0.0.0 | 將服務暴露給所有網路介面。綁定到特定介面以限制攻擊面 |
安全反模式
| 嚴重性 | 反模式 | 為何失敗 | 修正方式 |
|---|---|---|---|
| 高 | 透過隱晦實現安全 | 隱藏 URL 可透過模糊測試、日誌或原始碼發現 | 在所有端點上實施身分驗證 + 授權 |
| 高 | 信任客戶端標頭 | X-Forwarded-For、X-Is-Admin 可輕易偽造 |
伺服器端身分驗證 |
| 高 | 客戶端授權 | JavaScript 檢查可被任何 HTTP 客戶端繞過 | 在每個處理器上進行伺服器端權限檢查 |
| 高 | 跨環境共用機密 | 測試環境遭入侵會導致正式環境受損 | 透過機密管理工具為每個環境設定獨立機密 |
| 嚴重 | 忽略密碼學錯誤 | _, _ = encrypt(data) 會默默地以未加密方式繼續 |
始終檢查錯誤——失敗時關閉,絕不開放 |
| 嚴重 | 自行實作密碼學 | 自訂加密未經密碼學家分析 | 使用 crypto/aes GCM、golang.org/x/crypto/argon2 |
詳細的反模式與 Go 程式碼範例,請參閱 安全架構。
交叉參考
請參閱 samber/cc-skills-golang@golang-database、samber/cc-skills-golang@golang-safety、samber/cc-skills-golang@golang-observability、samber/cc-skills-golang@golang-continuous-integration 技能。
- → 請參閱
samber/cc-skills-golang@golang-continuous-integration技能,了解如何在 CI 中使用這些指南進行自動化 AI 驅動的程式碼審查




