正在加载,请稍候…

DevSecOps:在 CI/CD 流水线中左移安全

将安全集成到 CI/CD 流水线的每个阶段。了解 SAST、DAST、SCA、容器扫描、IaC 安全扫描以及 DevSecOps 的安全门控。

DevSecOps:在 CI/CD 流水线中左移安全

DevSecOps:左移安全

CI/CD 流水线中的安全

代码提交 → SAST → SCA → 构建 → 容器扫描 → 部署 → DAST → 监控

DevSecOps:在 CI/CD 流水线中左移安全 插图

SAST(静态应用安全测试)

# GitHub Actions - SAST 流水线
name: Security Pipeline

on: [push, pull_request]

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # Semgrep SAST
      - name: Semgrep SAST
        uses: returntocorp/semgrep-action@v1
        with:
          config: "p/owasp-top-ten p/nodejs"
          auditOn: push
        env:
          SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

      # ESLint 安全规则
      - name: ESLint Security
        run: |
          npm install eslint-plugin-security eslint-plugin-no-secrets
          npx eslint --plugin security --rule 'security/detect-eval-with-expression: error' src/

      # Bandit for Python
      - name: Bandit Python SAST
        if: hashFiles('**/*.py') != ''
        run: |
          pip install bandit
          bandit -r . -f json -o bandit-report.json -ll
          cat bandit-report.json

      # 上传 SARIF 到 GitHub Security
      - name: Upload SAST results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: sast-results.sarif

SCA(软件组成分析)

  sca:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Snyk 漏洞扫描
      - name: Snyk SCA
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          command: test
          args: --severity-threshold=high --json > snyk-results.json

      # 许可证合规性
      - name: License Check
        run: |
          npx license-checker --onlyAllow "MIT;ISC;BSD-2-Clause;BSD-3-Clause;Apache-2.0" \
            --excludePrivatePackages \
            --failOn "GPL-2.0;GPL-3.0;AGPL-3.0"

      # OWASP Dependency Check
      - name: OWASP Dependency Check
        uses: dependency-check/Dependency-Check_Action@main
        with:
          project: 'myapp'
          path: '.'
          format: 'SARIF'
          args: --failOnCVSS 8

DevSecOps:在 CI/CD 流水线中左移安全 插图

基础设施即代码安全

  iac-security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Checkov - Terraform/K8s/Dockerfile 扫描
      - name: Checkov IaC Scan
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: infrastructure/
          framework: terraform,kubernetes,dockerfile
          soft_fail: false
          output_format: sarif
          output_file_path: checkov-results.sarif

      # Trivy for Terraform
      - name: Trivy IaC Scan
        run: |
          trivy config infrastructure/ \
            --exit-code 1 \
            --severity HIGH,CRITICAL \
            --format sarif -o trivy-iac.sarif

      # tfsec for Terraform
      - name: tfsec
        uses: aquasecurity/tfsec-action@v1.0.0
        with:
          working_directory: infrastructure/terraform/

容器安全扫描

  container-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Trivy container scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: sarif
          output: trivy-container.sarif
          severity: CRITICAL,HIGH
          exit-code: 1

      - name: Hadolint Dockerfile lint
        uses: hadolint/hadolint-action@v3.1.0
        with:
          dockerfile: Dockerfile
          failure-threshold: error

DevSecOps:在 CI/CD 流水线中左移安全 插图

DAST(动态应用安全测试)

  dast:
    runs-on: ubuntu-latest
    needs: [deploy-staging]
    steps:
      - name: OWASP ZAP Baseline Scan
        uses: zaproxy/action-baseline@v0.10.0
        with:
          target: https://staging.myapp.com
          rules_file_name: .zap/rules.tsv
          fail_action: true

      - name: Nuclei DAST
        uses: projectdiscovery/nuclei-action@main
        with:
          target: https://staging.myapp.com
          flags: "-severity critical,high -t cves/ -t exposures/"

安全质量门控

// security-gate.js - 如果发现安全问题则阻止部署
const fs = require('fs')

function checkSecurityGates() {
  const gates = []

  // 检查 SAST 结果
  const sast = JSON.parse(fs.readFileSync('semgrep-results.json'))
  const criticalFindings = sast.results.filter(r => r.extra.severity === 'ERROR')
  gates.push({
    name: 'SAST',
    passed: criticalFindings.length === 0,
    details: `${criticalFindings.length} 个严重发现`,
  })

  // 检查 SCA
  const snyk = JSON.parse(fs.readFileSync('snyk-results.json'))
  const criticalVulns = snyk.vulnerabilities?.filter(v => v.severity === 'critical') || []
  gates.push({
    name: 'SCA',
    passed: criticalVulns.length === 0,
    details: `${criticalVulns.length} 个严重漏洞`,
  })

  // 报告
  const failed = gates.filter(g => !g.passed)
  if (failed.length > 0) {
    console.error('安全门控失败:')
    failed.forEach(g => console.error(`  - ${g.name}: ${g.details}`))
    process.exit(1)
  }

  console.log('所有安全门控通过!')
}

checkSecurityGates()

DevSecOps 成熟度模型

级别 实践
1 - 基础 依赖扫描,SAST
2 - 发展中 容器扫描,IaC 检查
3 - 已定义 DAST,安全门控,策略即代码
4 - 已管理 威胁建模,安全混沌
5 - 已优化 持续安全,紫队协作