mcpField
I
integrating-sast-into-github-actions-pipeline

integrating-sast-into-github-actions-pipeline

github.com/mukul975安全35.2k142 次安装8 周前更新
代码仓库

关于 integrating-sast-into-github-actions-pipeline

该安全技能指导开发和安全团队在 GitHub Actions 中集成 SAST,以便在代码变更时检测漏洞。它结合 CodeQL、Semgrep、自定义规则、合并门禁及结果汇总。

主要功能

  1. 01配置 CodeQL 与 Semgrep 扫描
  2. 02创建组织专用 Semgrep 规则
  3. 03设置分支保护质量门禁
  4. 04调整误报并汇总安全发现

适用场景

  1. 01在拉取请求中自动扫描代码
  2. 02为多语言代码库统一配置 SAST
  3. 03阻止未通过安全检查的变更合并

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill integrating-sast-into-github-actions-pipeline

安装后在 Claude Code 中输入/integrating-sast-into-github-actions-pipeline确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

将 SAST 集成到 GitHub Actions 流水线

适用场景

  • 当开发团队需要在每次拉取请求上进行自动化代码级漏洞检测时
  • 当安全团队需要在组织内所有仓库中一致地强制执行 SAST 时
  • 当从手动或定期安全审查迁移到持续安全测试时
  • 当合规框架(SOC 2、PCI DSS、NIST SSDF)要求提供自动化代码分析证据时
  • 当 monorepo 中多种语言共存,需要在同一工作流下统一扫描时

不要使用于运行时漏洞检测(应改用 DAST)、扫描第三方依赖(应使用 Snyk 等 SCA 工具)或基础设施即代码扫描(应使用 Checkov 或 tfsec)。

前置条件

  • 已启用 GitHub Actions 的 GitHub 仓库
  • GitHub Advanced Security 许可证(私有仓库上运行 CodeQL 所必需;公共仓库免费)
  • 用于托管规则和 Semgrep App 仪表板的 Semgrep 账户(提供免费套餐)
  • 使用受支持语言的仓库代码:Python、JavaScript/TypeScript、Java、C/C++、C#、Go、Ruby、Swift、Kotlin

工作流

步骤 1:配置 CodeQL 分析工作流

创建一个 CodeQL 工作流,在拉取请求和每周计划上运行,以捕获现有代码中的漏洞。

# .github/workflows/codeql-analysis.yml
name: "CodeQL Analysis"

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: '30 2 * * 1'  # Weekly Monday 2:30 AM

jobs:
  analyze:
    name: Analyze (${{ matrix.language }})
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: ['javascript', 'python']

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-extended,security-and-quality

      - name: Autobuild
        uses: github/codeql-action/autobuild@v3

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"
步骤 2:添加 Semgrep 扫描以支持自定义规则

Semgrep 通过更快的扫描和对自定义基于模式的规则的支持来补充 CodeQL。将其配置为将 SARIF 结果上传到同一个 GitHub Security 选项卡。

# .github/workflows/semgrep.yml
name: "Semgrep SAST Scan"

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main]

jobs:
  semgrep:
    name: Semgrep Scan
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read

    container:
      image: semgrep/semgrep:latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Run Semgrep
        run: |
          semgrep ci \
            --config auto \
            --config p/owasp-top-ten \
            --config p/cwe-top-25 \
            --sarif --output semgrep-results.sarif \
            --severity ERROR \
            --error
        env:
          SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: semgrep-results.sarif
          category: semgrep
步骤 3:为组织模式创建自定义 Semgrep 规则

编写组织特定的规则,以捕获代码库中独有的模式,例如已弃用的内部 API 或不安全的配置模式。

# .semgrep/custom-rules.yml
rules:
  - id: hardcoded-database-url
    patterns:
      - pattern: |
          $DB_URL = "...$PROTO://...:...$PASS@..."
    message: |
      Hardcoded database connection string with credentials detected.
      Use environment variables or a secrets manager instead.
    languages: [python, javascript, typescript]
    severity: ERROR
    metadata:
      cwe: "CWE-798: Use of Hard-coded Credentials"
      owasp: "A07:2021 - Identification and Authentication Failures"

  - id: unsafe-deserialization
    patterns:
      - pattern-either:
          - pattern: pickle.loads(...)
          - pattern: yaml.load(..., Loader=yaml.Loader)
          - pattern: yaml.load(..., Loader=yaml.FullLoader)
    message: |
      Unsafe deserialization detected. Use safe alternatives to prevent
      remote code execution vulnerabilities.
    languages: [python]
    severity: ERROR
    metadata:
      cwe: "CWE-502: Deserialization of Untrusted Data"

  - id: missing-csrf-protection
    patterns:
      - pattern: |
          @app.route("...", methods=["POST"])
          def $FUNC(...):
              ...
      - pattern-not-inside: |
          @csrf.exempt
          ...
    message: "POST endpoint may lack CSRF protection."
    languages: [python]
    severity: WARNING
步骤 4:通过分支保护建立质量门禁

配置分支保护规则,要求 SAST 检查在合并前通过,防止有漏洞的代码进入生产分支。

# Use GitHub CLI to set branch protection requiring SAST checks
gh api repos/{owner}/{repo}/branches/main/protection \
  --method PUT \
  --field required_status_checks='{"strict":true,"contexts":["Analyze (javascript)","Analyze (python)","Semgrep Scan"]}' \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":1}'
步骤 5:调整并抑制误报

通过 CodeQL 查询过滤器和 Semgrep nosemgrep 注释管理误报,以维持开发者对扫描结果的信任。

# codeql-config.yml - Custom CodeQL configuration
name: "Custom CodeQL Config"
queries:
  - uses: security-extended
  - uses: security-and-quality
  - excludes:
      id: js/unused-local-variable
paths-ignore:
  - '**/test/**'
  - '**/tests/**'
  - '**/vendor/**'
  - '**/node_modules/**'
  - '**/*.test.js'
  - '**/*.spec.py'
# Example: Suppressing a known false positive in Semgrep
import subprocess

def run_safe_command(cmd_list):
    # nosemgrep: python.lang.security.audit.dangerous-subprocess-use
    result = subprocess.run(cmd_list, capture_output=True, text=True, shell=False)
    return result.stdout
步骤 6:汇总并报告发现

使用 GitHub Security Overview 仪表板,并配置跨仓库安全警报的通知。

# Query SARIF results via GitHub API for reporting
gh api repos/{owner}/{repo}/code-scanning/alerts \
  --jq '.[] | select(.state=="open") | {rule: .rule.id, severity: .rule.security_severity_level, file: .most_recent_instance.location.path, line: .most_recent_instance.location.start_line}'

# Count open alerts by severity
gh api repos/{owner}/{repo}/code-scanning/alerts \
  --jq '[.[] | select(.state=="open")] | group_by(.rule.security_severity_level) | map({severity: .[0].rule.security_severity_level, count: length})'

关键概念

术语定义
SAST静态应用安全测试——在不执行源代码的情况下分析源代码,以发现安全漏洞
SARIF静态分析结果交换格式——用于表达静态分析工具结果的标准化 JSON 格式
CodeQLGitHub 的语义代码分析引擎,将代码视为数据并查询其漏洞模式
Semgrep轻量级静态分析工具,使用模式匹配来发现多种语言中的缺陷和安全问题
Security ExtendedCodeQL 查询套件,包含默认集之外的额外安全查询,用于更深入的分析
质量门禁自动化检查点,除非满足安全标准,否则阻止代码在流水线中推进
误报错误地将安全代码识别为有漏洞的扫描发现,需要抑制或调整

工具与系统

  • CodeQL:GitHub 的语义代码分析引擎,具备深度数据流和污点跟踪分析
  • Semgrep:快速、轻量级的模式匹配 SAST 工具,拥有 3000+ 社区规则和自定义规则支持
  • GitHub Advanced Security:在 GitHub 中提供代码扫描、机密扫描和依赖审查的平台
  • SARIF Viewer:VS Code 扩展,用于在开发过程中本地审查 SARIF 结果
  • GitHub Security Overview:组织级仪表板,汇总所有仓库的安全警报

常见场景

场景:多语言 Monorepo 需要统一的 SAST

背景:一个平台团队管理着一个 monorepo,其中包含 Python 微服务、TypeScript 前端和 Go 基础设施工具。安全审查每季度手动进行一次,在两次审查之间会遗漏漏洞。

做法:

  1. 使用覆盖 Python、JavaScript 和 Go 语言的矩阵策略配置 CodeQL
  2. 添加带 --config auto 的 Semgrep,以自动检测语言并应用相关规则集
  3. 创建基于路径的触发器,使只有发生变更的语言目录才触发各自的扫描
  4. 将所有 SARIF 结果上传到 GitHub Security 标签页,并按工具和语言使用唯一类别
  5. 设置分支保护,要求所有 SAST 作业在合并前通过
  6. 安排每周全仓库扫描,以根据新发布的 CVE 模式发现未变更代码中的问题

陷阱:将 CodeQL 设置为在每个 PR 上分析所有语言会显著增加 CI 时间。使用路径过滤器仅触发相关语言的扫描。Semgrep 的 --config auto 可能启用与 CodeQL 发现冲突的规则,从而产生重复告警。

场景:降低高误报率带来的告警疲劳

背景:启用 SAST 后,开发人员会忽略发现项,因为其中 40% 是误报,从而削弱了安全计划。

做法:

  1. 导出所有当前告警,并将其分类为真阳性、误报或信息性
  2. 创建自定义 CodeQL 配置,排除会产生最多误报的高噪声查询 ID
  3. 为测试文件、生成代码和 vendored 依赖编写 .semgrepignore 模式
  4. 建立每周分诊会议,由安全和开发负责人审查新规则添加
  5. 将误报率作为指标跟踪,并以低于 15% 为目标,以赢得开发人员信任

陷阱:为了减少噪声而过度抑制规则可能会造成盲点。始终根据 OWASP Top 10 和 CWE Top 25 验证抑制项,以确保关键漏洞类别仍被覆盖。

输出格式

SAST Pipeline Scan Report
==========================
Repository: org/web-application
Branch: feature/user-auth-refactor
Scan Date: 2026-02-23
Commit: a1b2c3d4

CodeQL Results:
  Language    Queries Run   Findings   Critical   High   Medium
  javascript  312           4          1          2      1
  python      287           2          0          1      1

Semgrep Results:
  Ruleset          Rules Matched   Findings   Errors   Warnings
  auto             1,847           3          1        2
  owasp-top-ten    186             2          1        1
  custom-rules     12              1          0        1

QUALITY GATE: FAILED
  Blocking findings: 2 Critical/High severity issues
  - [CRITICAL] CWE-89: SQL Injection in src/api/users.py:47
  - [HIGH] CWE-79: Cross-site Scripting in src/components/Search.tsx:123

Action Required: Fix blocking findings before merge is permitted.

评论

支持 Markdown