EP.08 — DevOps 實戰系列

DevSecOps:
將安全植入自動化流程

不要讓「安全」成為部署的阻礙。學習如何在 CI/CD 的每一秒鐘,自動偵測漏洞、掃描秘密資訊與保護容器鏡像。

📅
2026 年 5 月
✍️
Joseph Chen
25 分鐘閱讀

痛點:最後一刻的「安全檢查」是部署的噩夢

在傳統的開發流程中,安全檢查通常發生在最後一刻。想像一下:你花了三週開發新功能,程式碼已經準備好上線,QA 也測過了,結果資安部門突然說:「這段程式碼有 SQL Injection 風險,還有三個過時的套件有嚴重漏洞,不能部署。」

這會導致什麼後果?

  • 部署中斷原本計畫好的發佈時間被迫延後,影響業務目標。

  • 高昂的修補成本在開發後期修補漏洞的成本,是開發初期的 10 倍以上。

  • 團隊對立開發團隊覺得資安是「阻礙者」,資安團隊覺得開發是「風險製造者」。

這就是為什麼我們需要 DevSecOps。它的核心理念是 「左移 (Shift-Left Security)」 —— 從寫下第一行程式碼開始,就把安全性整合到自動化流程中。


一、SAST:在程式碼編譯前找出問題

SAST (Static Analysis Security Testing) 就像是資安版的 Linter。它不需要執行程式碼,而是直接掃描源碼,尋找不安全的寫法。

為什麼 SAST 很重要?

它可以抓到常見的人為錯誤,例如:

❌ 不安全的寫法 (SQLi)

typescript
// 極度危險!直接拼接字串
const query = "SELECT * FROM users WHERE id = '" + userInput + "'";
db.execute(query);

✅ 安全的寫法 (Prepared Statement)

typescript
// 安全:使用參數化查詢
const query = "SELECT * FROM users WHERE id = ?";
db.execute(query, [userInput]);

在 GitHub Actions 中,我們可以使用開源工具如 SonarQubeSemgrep 來自動執行:

.github/workflows/security.yml
name: Security Scan
on: [push, pull_request]

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Semgrep
        run: |
          docker run --rm -v "$(pwd):/src" returntocorp/semgrep semgrep             --config=p/default             --error

二、SCA:掃描你的第三方套件漏洞

現代應用程式 80% 的程式碼其實來自開源套件。你可能寫了完美的程式碼,但如果你依賴的 npm 套件有後門或漏洞,你的整個系統都是脆弱的。

SCA (Software Composition Analysis) 會比對你的依賴清單(如 package.json)與全球漏洞資料庫 (CVE)。

實戰建議:GitHub Dependabot

這是最簡單的 SCA 工具。在 GitHub Repo 的 Settings -> Security 中開啟它,它會自動偵測漏洞,甚至幫你開 Pull Request 自動更新套件版本。

手動執行掃描:

終端機指令
# Node.js 內建檢查
npm audit

# 使用 Snyk (業界常用工具)
snyk test

三、Secret Detection:防止 API Key 外洩

這是最常見的慘案:工程師不小心把 AWS Access KeyDatabase Password 寫在程式碼裡,然後 `git push` 到公開倉庫。
駭客通常在 1 分鐘內就會掃描到並盜用你的帳號。

// ❌ 千萬不要這樣做!

const STRIPE_API_KEY = "sk_test_51...your_secret_key";

// ✅ 正確做法:使用環境變數

const STRIPE_API_KEY = process.env.STRIPE_SECRET;

我們可以使用 gitleaks 這樣的工具,在 CI 流程中阻斷包含敏感資訊的提交:

.github/workflows/secret-scan.yml
name: Secret Scan
on: [push]
jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

四、Container Security:保護你的運行環境

在 DevOps 世界,我們把程式碼包進 Docker Image。但如果你的 Base Image (例如舊版的 Ubuntu 或 Node) 本身就有漏洞呢?

我們需要掃描 Docker Image。這兩年最受歡迎的工具是 Trivy。它不僅能掃描 OS 漏洞,還能檢查配置錯誤。

使用 Trivy 掃描 Docker Image
# 掃描本地 Image 的漏洞
trivy image my-app:latest

# 只顯示「嚴重 (Critical)」等級的漏洞,並產生 JSON 報告
trivy image --severity CRITICAL --format json --output results.json my-app:latest

Dockerfile 安全實戰清單

1

不要使用 Root 使用者

在 Dockerfile 中使用 USER 指令切換至非特權使用者。這可以防止駭客即便攻破應用程式,也無法獲得主機的完整權限。

RUN useradd -m appuser && USER appuser
2

固定版本號 (Immutable Tags)

不要使用 node:latest,因為它每天都在變。使用 node:20.11.0-alpine 確保環境一致性且減少體積。

FROM node:20.11.0-alpine
3

移除不必要的工具

不要在 Production 鏡像中留下 curl、wget 或 git。駭客進入容器後會利用這些工具下載惡意程式。

RUN apk del curl

五、IaC Scanning:基礎設施也要掃描

現代 DevOps 使用 Terraform, Kubernetes (K8s)CloudFormation 來定義機器。
如果你的 S3 Bucket 被設定成「公開讀取」,或者你的 K8s Pod 擁有過大的權限,這就是嚴重的安全威脅。

實戰範例:使用 Checkov 掃描 Terraform

Checkov 是一個強大的開源工具,可以在你部署到 AWS 之前,先檢查你的設定檔是否符合資安最佳實踐。

Terraform 安全檢查
# 安裝 Checkov
pip install checkov

# 掃描目前的目錄
checkov -d . --check CKV_AWS_20,CKV_AWS_52

💡 常見的 IaC 配置錯誤:

  • S3 Bucket 開放公共訪問 (Public Read)
  • Security Group 開放 0.0.0.0/0 存取資料庫埠號
  • IAM Role 權限過大 (使用 AdministratorAccess)
  • EBS 磁碟未加密

六、軟體供應鏈安全:保護整個流程

2021 年的 **SolarWinds** 案告訴我們:即便程式碼沒問題,如果駭客攻進了你的 **CI/CD Server (GitHub Actions/Jenkins)**,他們就能在打包時偷偷塞進木馬。

二進位檔簽名

使用 Sigstore/Cosign 為你的 Docker Image 簽名,確保沒人中途掉包。

SLSA 框架

遵照 SLSA 標準,為建置過程提供不可篡改的證據。

SBOM (軟體清單)

產生軟體物料清單,清楚記錄每一層依賴關係。

產生 SBOM (Software Bill of Materials)
# 使用 Syft 產生 SBOM
syft my-app:latest -o json > sbom.json

# 檢視所有依賴套件與版本
cat sbom.json | jq '.artifacts[].name'

七、DAST:從外部模擬駭客攻擊

與 SAST 不同,DAST (Dynamic Analysis Security Testing) 是在應用程式「執行中」進行掃描。它不知道你的程式碼長怎樣,而是像駭客一樣從外面發送請求。

在 CI/CD 中,我們通常在部署到 Staging 環境後,自動觸發掃描:

OWASP ZAP 掃描範例
# 使用 Docker 執行快速掃描
docker run -t owasp/zap2docker-stable zap-baseline.py \
    -t https://staging.chullin.tw \
    -r report.html
SAST (內部掃描)

「這行程式碼看起來不安全,可能會有 XSS 問題。」

早期發現、速度快
DAST (外部掃描)

「我試著注入腳本,結果伺服器真的執行了!這是漏洞。」

真實性高、但較晚執行

總結:DevSecOps 是全生命週期的守護

DevSecOps 不只是一堆工具的堆疊,而是一種文化的轉變。身為軟體工程師,我們有責任寫出安全的程式碼,而身為 DevOps 工程師,我們有責任建立一個「讓安全變得簡單」的自動化流程。

寫 Code

IDE Plugin / pre-commit

提交 PR

SAST + SCA

構建 Image

Container Scanning

部署後

DAST + Monitoring