結論先講
安全測試分兩種:看 code(SAST)和打 API(DAST)。兩個都要做,而且都能自動化塞進 CI/CD。 不需要資安背景,不需要買昂貴的工具,開源方案就能擋掉 80% 的常見漏洞。
真實場景:我們的 EC 專案在 seeder 裡隨機把測試帳號加入黑名單,導致所有角色的權限測試都失敗。這算不算安全問題?算。Seeder 汙染了 RBAC 系統的資料完整性。
安全測試的三個層次
Layer 1: 依賴掃描 — 你用的套件有沒有已知漏洞
Layer 2: SAST — 你寫的 code 有沒有安全問題
Layer 3: DAST — 你的 API 能不能被攻擊
Layer 1:依賴掃描(最簡單、最該先做)
你的專案依賴幾十甚至幾百個套件,其中任何一個有漏洞,你的應用就有漏洞。
# Node.js
npm audit
# 或更好的
npx audit-ci --high
# Python
pip-audit
safety check
# Go
govulncheck ./...CI 整合
# .github/workflows/security.yml
dependency-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm audit --audit-level=high
# high 以上的漏洞 → 失敗GitHub Dependabot(免費)
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10Dependabot 會自動開 PR 升級有漏洞的依賴。零成本,沒有理由不開。
Layer 2:SAST(Static Application Security Testing)
SAST 掃描你的原始碼,找出可能的安全問題。不需要跑應用程式。
常見的 SAST 工具
| 工具 | 語言 | 免費 | 說明 |
|---|---|---|---|
| Semgrep | 多語言 | ✅ | 規則豐富,社群活躍 |
| CodeQL | 多語言 | ✅ (GitHub) | GitHub 原生整合 |
| Bandit | Python | ✅ | Python 專用 |
| ESLint Security | JS/TS | ✅ | ESLint 外掛 |
| SonarQube | 多語言 | 社群版免費 | 功能最完整 |
Semgrep 範例
# 安裝
pip install semgrep
# 掃描(用 OWASP Top 10 規則)
semgrep --config=p/owasp-top-ten .Semgrep 能抓到的問題:
# ❌ SQL Injection
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# ✅ 安全寫法
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))// ❌ XSS
element.innerHTML = userInput;
// ✅ 安全寫法
element.textContent = userInput;CI 整合
sast-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Semgrep scan
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/javascript
p/pythonLayer 3:DAST(Dynamic Application Security Testing)
DAST 實際對你的應用發送攻擊請求,看能不能打穿。需要應用程式在跑。
OWASP ZAP(免費、最多人用)
# Docker 一行啟動
docker run -t ghcr.io/zaproxy/zaproxy:stable \
zap-baseline.py -t https://your-api.com
# 或 API 掃描
docker run -t ghcr.io/zaproxy/zaproxy:stable \
zap-api-scan.py -t https://your-api.com/openapi.yaml -f openapiZAP 會自動測試:
- SQL Injection
- XSS(Cross-Site Scripting)
- CSRF(Cross-Site Request Forgery)
- 路徑穿越(Path Traversal)
- 敏感資訊洩漏(Header、Error Message)
- 不安全的 Cookie 設定
ZAP 掃描報告範例
WARN-NEW: X-Frame-Options Header Not Set [10020]
WARN-NEW: Server Leaks Version Information [10036]
FAIL-NEW: SQL Injection - SQLite [40024]
FAIL-NEW: Cross Site Scripting (Reflected) [40012]
CI 整合
dast-scan:
runs-on: ubuntu-latest
services:
app:
image: your-app:latest
ports:
- 8080:8080
steps:
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'http://app:8080'
rules_file_name: 'zap-rules.tsv'
fail_action: 'true' # 有 FAIL 就中斷 CIOWASP Top 10 測試對照
工程師至少要知道這十個,每個都有對應的自動化測試方式:
| # | 漏洞 | SAST 能抓 | DAST 能抓 | 工具 |
|---|---|---|---|---|
| A01 | 存取控制失效 | ⚠️ 部分 | ✅ | ZAP + 自訂腳本 |
| A02 | 加密機制失效 | ✅ | ⚠️ 部分 | Semgrep |
| A03 | 注入攻擊 | ✅ | ✅ | Semgrep + ZAP |
| A04 | 不安全的設計 | ❌ | ❌ | 需人工審查 |
| A05 | 安全設定錯誤 | ⚠️ 部分 | ✅ | ZAP |
| A06 | 脆弱過時元件 | ✅ | ❌ | npm audit / Dependabot |
| A07 | 身分驗證失效 | ⚠️ 部分 | ✅ | ZAP + 自訂腳本 |
| A08 | 軟體資料完整性 | ✅ | ❌ | Semgrep |
| A09 | 日誌監控不足 | ❌ | ❌ | 需架構審查 |
| A10 | SSRF | ✅ | ✅ | Semgrep + ZAP |
SAST + DAST + 依賴掃描能自動化覆蓋約 70% 的 OWASP Top 10。 剩下 30% 需要人工 code review 和架構審查。
最小可行的安全測試方案
如果你的專案現在什麼安全測試都沒有,按這個順序加:
第一步:開 Dependabot(5 分鐘)
加一個 .github/dependabot.yml,完成。
第二步:CI 加 npm audit(10 分鐘)
- run: npm audit --audit-level=high第三步:加 ESLint Security Plugin(15 分鐘)
npm install -D eslint-plugin-security// .eslintrc
{
"plugins": ["security"],
"extends": ["plugin:security/recommended"]
}第四步:CI 加 Semgrep(20 分鐘)
用 GitHub Action,零設定。
第五步:定期跑 ZAP(看情況)
如果有 staging 環境,每週跑一次 ZAP baseline scan。
常見問題
安全測試會不會很慢?
依賴掃描和 SAST 都是秒級到分鐘級。DAST 比較慢(5-30 分鐘),建議不要每次 commit 都跑,排在 nightly build 或 merge to main 時。
掃出來的問題太多怎麼辦?
先修 FAIL(Critical/High),WARN 排進 backlog。不要試圖一次全修,那會讓你放棄。
小專案需要安全測試嗎?
至少開 Dependabot 和 npm audit。成本幾乎是零,但能擋掉已知漏洞的依賴。
SAST 誤報率高嗎?
看工具。Semgrep 的誤報率相對低,因為它的規則比較精確。SonarQube 的誤報率較高但覆蓋更廣。建議先用 Semgrep,有需要再加其他。