程式碼裡的一行小疏忽,就是巨人攻破城牆的缺口。
在開始導入安全檢查之前,先說一下背景。
我原本是網路工程師,日常工作多半圍繞在網路維運、權限控管,像 Active Directory 的操作權限設定。嚴格說起來,這些雖然跟資安沾邊,但偏基礎,並不直接涉及應用程式或軟體開發的安全。
也因為這樣,踏進 DevSecOps 的直覺是:這很像我以前管網路,只是守門位置從交換機、防火牆,延伸到整個軟體生命週期。
安全檢查(特別是 SAST 這類靜態分析工具)就是這個概念的體現。
在程式碼還沒部署前,就能先檢查出潛在的危險語法,避免弱點跟著進入生產環境。
過去我在做的是「守住誰能進網路門口」
而現在我要學會的是「在軟體還沒出門前,就把漏洞攔下來」。
那我們就正式進入今天的重點吧
功能測試過關,不代表系統安全,只代表它能正常跑。
DevSecOps 的做法是把安全檢查左移到日常開發與 CI:在程式上線前,就先把可能的洞找出來、擋下來。今天用Bandit,把「巡牆」這件事自動化——每次提交都掃一次,裂縫別留到明天。
SAST 是在「不執行程式」的狀態下,直接從原始碼找安全風險。它補的是功能測試看不到的盲區,常見像:
eval
/ exec
、subprocess(..., shell=True)
)hashlib.md5
、random
拿去做安全用途)requests(..., verify=False)
)SAST 不就多一層檢查,會不會拖慢節奏?
在本機你可以只掃改到的檔案、或在 commit 前跑一次;完整掃描交給 CI。養成小步快掃的節奏,效能與安心感會一起上來。
安裝:
pip install bandit
掃描整個專案:
bandit -r .
掃描單檔或特定目錄:
bandit app.py
bandit -r src/
判讀結果(範例):
>> Issue: [B307:blacklist] Use of possibly insecure function - eval.
Severity: High Confidence: High
Location: app.py:42
掃出一大堆警告,要全修嗎?
不必追求 0 警告。先處理 High 嚴重 + High 可信 的項目;Medium 視情況排期;Low 多半是提醒。把風險排序,比盲修有效。
(a) 危險執行
# ❌ 風險:任意輸入可被執行(B307/B102)
eval(user_input)
# ✅ 安全做法:白名單或結構化解析
import ast
safe_value = ast.literal_eval(user_input) # 僅允許字面常量
(b) Shell 注入
# ❌ 風險:shell=True(B602)
subprocess.run(f"ls {arg}", shell=True)
# ✅ 安全做法:避免 shell,使用參數陣列
subprocess.run(["ls", arg], check=True)
(c) 不安全的雜湊/隨機數
# ❌ 風險:弱雜湊 / 非安全用途隨機(B303)
hashlib.md5(password).hexdigest()
# ✅ 安全做法:使用強雜湊或 KDF
import hashlib
hashlib.sha256(password).hexdigest()
(d) 關閉憑證驗證
# ❌ 風險:跳過 SSL 驗證(B501)
requests.get(url, verify=False)
# ✅ 安全做法:保留驗證,必要時配置信任根
requests.get(url, timeout=10) # 預設 verify=True
遇到誤報怎麼辦?
可以在單行末尾加 # nosec 暫時忽略,但務必附註理由,例如:
safe_eval = ast.literal_eval(user_input) # nosec: literal_eval 限制了輸入型態
或集中管理在設定檔排除特定路徑/規則,避免把真正的洞當誤報蓋過去。
在專案根目錄加入 bandit.yaml,統一規則與門檻:
# bandit.yaml
exclude_dirs:
- tests
- venv
- .venv
# 只擋中高風險、判斷可信度至少 Medium
severity: medium
confidence: medium
執行時帶上設定:
bandit -r . -c bandit.yaml
好處:
在你現有的 ci.yml 加一個步驟即可(放在 lint 後、測試前或後都行):
- name: Security check (Bandit)
run: |
bandit -r . -c bandit.yaml \
--severity-level medium \
--confidence-level medium \
-f json -o bandit-report.json
城牆不會瞬間崩塌,但裂縫沒人看,總有一天會變缺口。
把 Bandit 放進你的流程,就是安排一支不下線的巡邏隊,安靜但有效。