nadiarahmadinaa/secure-cicd-pipeline

GitHub: nadiarahmadinaa/secure-cicd-pipeline

一套基于GitHub Actions的四层安全CI/CD流水线,通过密钥检测、静态分析、容器扫描和动态测试在代码合并前自动拦截安全漏洞。

Stars: 1 | Forks: 0

# 安全的 CI/CD 流水线 一个 GitHub Actions 流水线,在每次 push 和 pull request 时强制执行**四个自动化安全门**。有漏洞的代码会在合并前被拦截——而不是在部署后被发现。 **在线演示:** 从 `vuln-demo` 分支创建一个 PR,即可看到所有四个门被触发并阻止合并。 ## 流水线工作原理 ``` Push / Pull Request │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ GATE 1 ── Secrets Detection Gitleaks │ │ Scans full git history for credentials │ │ ↓ BLOCKS on any matched secret │ │ │ │ GATE 2 ── Static Analysis (SAST) CodeQL │ │ Traces data flow for injection, path traversal, etc. │ │ ↓ BLOCKS on error-level findings │ │ │ │ BUILD ─── Docker image docker/build-push-action │ │ Multi-stage, non-root, read-only filesystem │ │ ↓ │ │ │ │ GATE 3 ── Container Scanning Trivy │ │ CVEs in OS packages + pip dependencies │ │ ↓ BLOCKS on unfixed HIGH/CRITICAL CVEs │ │ │ │ GATE 4 ── Dynamic Analysis (DAST) OWASP ZAP │ │ Spins up the live container, active + passive scan │ │ ↓ BLOCKS on FAIL-severity HTTP security alerts │ │ │ │ SUMMARY ─ Aggregated gate result │ │ Required status check → blocks PR merge │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ✅ Safe to deploy / ❌ Blocked with findings in Security tab ``` 所有发现的结果都会以 SARIF 格式上传,并显示在 **GitHub → Security → Code scanning alerts** 中,为这四个工具提供了一个统一的分诊界面。 ## 为什么选择这四个工具 每一层都能捕获其他工具遗漏的不同类别的漏洞。 ### Gitleaks — 密钥检测 提交到 git 历史中的密钥会永久泄露,即使删除后也是如此。Gitleaks 会针对涵盖 AWS 密钥、GitHub token、私钥、连接字符串等内容的 130 多种模式扫描**整个提交历史**(而不仅仅是 diff)。 它**首先**运行以实现快速失败:如果硬编码的凭据已经存在于代码树中,再花 5 分钟进行 SAST 扫描就毫无意义了。 通过 `.gitleaks.toml` 进行配置,包含针对 Flask `SECRET_KEY`、数据库 URL 和内部 API 密钥的自定义规则,以及用于抑制测试夹具中误报的白名单。 ### CodeQL — 静态应用程序安全测试 (SAST) CodeQL 将代码建模为可查询的数据库,并追踪从不受信任的输入源(HTTP 参数、环境变量)到危险汇聚点的**数据流**(SQL 查询、shell 命令、文件路径)。由于它能理解控制流,因此可以捕获基于正则表达式的扫描器遗漏的漏洞。 使用 `security-extended` 查询套件,涵盖: - SQL 注入、命令注入、路径遍历 - 硬编码凭据和弱加密 - 不安全的反序列化和不安全的反射 - XSS 和开放重定向 门脚本会解析 SARIF 输出,并在出现任何 `error` 级别的发现时使构建失败。`warning` 级别的发现会在 Security 选项卡中可见,但不会阻止构建。 ### Trivy — 容器扫描 容器是一种供应链产物:它捆绑了操作系统、系统库和语言包,其中每一个都可能包含已知的 CVE。Trivy 扫描的是**构建好的镜像**(而不仅仅是 `requirements.txt`),因为操作系统层对基于 pip 的扫描器是不可见的。 三次扫描: 1. **镜像 CVE** — 构建镜像中的操作系统包和 pip 依赖项 2. **文件系统** — 源代码仓库,用于查找密钥和 Dockerfile 配置错误 3. **IaC** — Dockerfile 最佳实践检查(非 root 用户、HEALTHCHECK 等) 该门会在检测到 `HIGH` 和 `CRITICAL` 级别的未修复 CVE 时阻止构建。CVE 例外情况需要在 `.trivyignore` 中添加条目,并附带书面理由和复审日期。 ### OWASP ZAP — 动态应用程序安全测试 (DAST) SAST 分析源代码;DAST 测试的是**运行中的应用程序**。ZAP 能发现仅在运行时出现的漏洞:缺失的安全头、CSRF 暴露、身份验证绕过,以及静态不可见的注入面。 工作流会启动通过了 Trivy 扫描的完全相同的 Docker 镜像(相同的产物),植入测试数据,然后运行基线扫描(被动爬虫 + 主动检查)。警报处理通过 `.github/zap/zap-rules.tsv` 按规则控制: | 分类 | 效果 | |---|---| | `FAIL` | 非零退出 → 流水线被阻止 | | `WARN` | 记录在报告中,不阻止 | | `IGNORE` | 完全抑制 | ## 安全门演示 `vuln-demo` 分支包含故意的漏洞,以展示每个门是如何触发的。从它向 `main` 分支发起一个 PR 并观察: | 安全门 | 发现内容 | 漏洞代码 | |------|---------|----------------| | Gitleaks | 硬编码的 API 密钥 | `examples/vulnerable_app.py:7` | | CodeQL | SQL 注入 (CWE-89) | `examples/vulnerable_app.py:26` | | CodeQL | 操作系统命令注入 (CWE-78) | `examples/vulnerable_app.py:34` | | CodeQL | 路径遍历 (CWE-22) | `examples/vulnerable_app.py:40` | | Trivy | 取决于基础镜像的 CVE 状态 | 镜像扫描 | | ZAP | 缺少安全头 | 运行时扫描 | 创建演示分支: ``` git checkout -b vuln-demo # CodeQL 扫描 app/ — 暂时将 examples/vulnerable_app.py 移动或复制到此处 cp examples/vulnerable_app.py app/vulnerable_routes.py git add app/vulnerable_routes.py git commit -m "demo: add vulnerable routes to trigger security gates" git push origin vuln-demo # 打开 PR: vuln-demo → main ``` ## 仓库结构 ``` . ├── .github/ │ ├── codeql/ │ │ └── codeql-config.yml # Query suite (security-extended) + path filters │ ├── scripts/ │ │ └── zap-to-sarif.py # Converts ZAP JSON report → SARIF 2.1.0 │ ├── workflows/ │ │ └── security-pipeline.yml # All four gates + summary job │ ├── zap/ │ │ └── zap-rules.tsv # Per-alert FAIL / WARN / IGNORE thresholds │ └── dependabot.yml # Weekly updates: Actions, pip, Docker base image ├── app/ │ ├── app.py # Hardened Flask REST API (the scan target) │ ├── docker-compose.yml # Local development │ ├── Dockerfile # Multi-stage, non-root, read-only filesystem │ └── requirements.txt ├── examples/ │ └── vulnerable_app.py # Annotated vulnerable code — gates demo ├── .gitleaks.toml # Custom rules + allowlist ├── .trivyignore # CVE exceptions (require justification) ├── SECURITY.md # Disclosure policy + gate configuration guide └── README.md ``` ## 目标应用程序演示了什么 `app/app.py` 是一个 Flask REST API,旨在展示默认安全模式——与 `examples/vulnerable_app.py` 形成对比: | 关注点 | 安全实现 | |---------|----------------------| | SQL 查询 | 参数化(`?` 占位符)——不使用字符串格式化 | | 密码存储 | PBKDF2-SHA256,260,000 次迭代,每用户随机盐 | | 安全头 | 每次响应都带有 CSP, HSTS, X-Frame-Options, X-Content-Type-Options | | 速率限制 | 通过 `flask-limiter` 实现的按端点限制 | | 输入验证 | 在任何处理之前进行长度、类型和字符类别检查 | | 容器用户 | UID 1001 非root用户,只读文件系统,丢弃所有 capabilities | ## 设置 ### 1. 推送到 GitHub ``` git init git remote add origin https://github.com//secure-cicd-pipeline.git git add . git commit -m "feat: secure CI/CD pipeline with four security gates" git push -u origin main ``` ### 2. 启用代码扫描 **Settings → Security → Code security:** - ✅ Dependency graph - ✅ Dependabot alerts + security updates - ✅ Code scanning (CodeQL + Trivy + ZAP SARIF upload here) - ✅ Secret scanning ### 3. 要求将门作为合并检查 **Settings → Branches → Add rule → `main`:** ``` ✅ Require status checks to pass before merging → Required check: "Security Gate Summary" ✅ Require branches to be up to date before merging ✅ Require signed commits ✅ Do not allow bypassing the above settings ``` 设置完成后,除非所有四个门都通过,否则任何 PR 都无法合并。 ### 4. 可选密钥 | Secret | 目的 | |--------|---------| | `GITLEAKS_LICENSE` | 高级 Gitleaks 规则集(私有仓库) | ## 本地运行 ``` # 启动 API cd app && docker-compose up --build # 测试 endpoints curl http://localhost:5000/health curl -X POST http://localhost:5000/api/users \ -H "Content-Type: application/json" \ -d '{"username":"alice","password":"Str0ng!Pass"}' curl -X POST http://localhost:5000/api/items \ -H "Content-Type: application/json" \ -d '{"name":"Widget","description":"A test item"}' # 运行 Gitleaks docker run --rm -v "$(pwd):/repo" zricethezav/gitleaks:latest \ detect --source=/repo -c /repo/.gitleaks.toml -v # 运行 Trivy trivy image --severity HIGH,CRITICAL secure-api:local # 运行 ZAP baseline docker run --rm -t ghcr.io/zaproxy/zaproxy:stable \ zap-baseline.py -t http://host.docker.internal:5000 -I ``` ## 调整阈值 | 文件 | 更改内容 | |------|---------------| | `.github/workflows/security-pipeline.yml` | `FAIL_SEVERITY` 环境变量 (`CRITICAL` / `HIGH` / `MEDIUM`) | | `.github/codeql/codeql-config.yml` | 查询套件,`paths`,`paths-ignore` | | `.github/zap/zap-rules.tsv` | 每个警报的 `FAIL` / `WARN` / `IGNORE` | | `.trivyignore` | 带有理由注释的 CVE 例外情况 | | `.gitleaks.toml` | 自定义模式和白名单条目 | ## 许可证 MIT
标签:CI/CD安全, Claude, CodeQL, CVE检测, DAST, DevSecOps, Docker, GitHub Actions, Gitleaks, Llama, OWASP ZAP, SAST, StruQ, Web安全, Web截图, 上游代理, 代码安全, 动态应用安全测试, 安全左移, 安全评估工具, 安全防御评估, 容器安全, 恶意软件分析, 漏洞枚举, 盲注攻击, 自动化安全门禁, 自动笔记, 蓝队分析, 请求拦截, 软件供应链安全, 远程方法调用, 逆向工具, 静态应用安全测试