正在加载,请稍候…

DevSecOps: Shifting Security Left in CI/CD Pipelines

Integrate security into every stage of your CI/CD pipeline. Learn SAST, DAST, SCA, container scanning, IaC security scanning, and security gates for DevSecOps.

DevSecOps: Shift Left Security

Security in CI/CD Pipeline

Code Commit → SAST → SCA → Build → Container Scan → Deploy → DAST → Monitor

SAST (Static Application Security Testing)

# GitHub Actions - SAST pipeline
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 security rules
      - 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

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

SCA (Software Composition Analysis)

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

      # Snyk vulnerability scanning
      - 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

      # License compliance
      - 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

Infrastructure as Code Security

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

      # Checkov - Terraform/K8s/Dockerfile scanning
      - 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 Security Scanning

  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

DAST (Dynamic Application Security Testing)

  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 Quality Gates

// security-gate.js - Fail deployment if security issues found
const fs = require('fs')

function checkSecurityGates() {
  const gates = []

  // Check SAST results
  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} critical findings`,
  })

  // Check 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} critical vulnerabilities`,
  })

  // Report
  const failed = gates.filter(g => !g.passed)
  if (failed.length > 0) {
    console.error('SECURITY GATES FAILED:')
    failed.forEach(g => console.error(`  - ${g.name}: ${g.details}`))
    process.exit(1)
  }

  console.log('All security gates passed!')
}

checkSecurityGates()

DevSecOps Maturity Model

Level Practices
1 - Basic Dependency scanning, SAST
2 - Developing Container scanning, IaC checks
3 - Defined DAST, security gates, policy as code
4 - Managed Threat modeling, security chaos
5 - Optimized Continuous security, purple teaming