AbdelazezMohamedAzez/secure-devsecops-starter

GitHub: AbdelazezMohamedAzez/secure-devsecops-starter

该项目通过一个加固的 Python Flask 应用,演示了如何在整个 CI/CD 流水线及多云部署中实现自动化安全门禁与 DevSecOps 最佳实践。

Stars: 1 | Forks: 0

# 安全 DevSecOps 入门项目 这是一个实操性的 Python Flask API 项目,用于练习和展示 DevSecOps 基础、安全的 CI/CD pipeline、自动化安全门禁、容器加固、左移安全、运行时 DAST 以及实践性的多云安全部署证据。 ## 项目概述 该项目最初只是一个简单的 Flask API,后来逐渐升级为一个经过加固的 DevSecOps 入门 pipeline。 其主要目标是演示如何在代码合并、部署或暴露到云环境之前,将安全检查集成到软件交付生命周期中。 该 pipeline 不仅会生成安全报告,还会在检测到高风险问题时强制执行阻断性安全门禁。 该仓库还包含了跨 AWS 和 GCP 的实际云部署证据,展示了基于 VM 的部署模型和托管式 serverless 容器部署模型。 ## 项目包含内容 - Python Flask API - Docker 化的应用 - GitHub Actions CI pipeline - 最小权限的 GitHub Actions 权限配置 - 基于分支的 PR 工作流 - 使用 Gitleaks 进行 secret 扫描 - 使用 Semgrep 进行 SAST 扫描 - 使用 CodeQL 进行代码扫描 - 使用 pip-audit 进行 Python 依赖项漏洞扫描 - 使用 Trivy 进行容器漏洞扫描 - 使用 OWASP ZAP Baseline Scan 进行 DAST 扫描 - 使用 Dependabot 自动化依赖项更新 - 本地 pre-commit 安全检查 - Docker 非 root 用户加固 - 基础的 Flask 安全响应头 - 作为 GitHub Actions artifacts 上传的安全扫描报告 - AWS EC2 实际部署证据 - GCP Cloud Run 实际部署证据 - Artifact Registry 镜像部署证据 - 运行时 Trivy 扫描证据 - 针对已部署云 endpoint 的 OWASP ZAP DAST 证据 - CI 与运行时容器扫描对比调查 - 临时云资源清理文档 ## 技术栈 | 领域 | 工具 / 服务 | |---|---| | 应用程序 | Python Flask | | Web 服务器 | Gunicorn | | 容器化 | Docker | | CI/CD | GitHub Actions | | Secret 扫描 | Gitleaks | | SAST | Semgrep | | 代码扫描 | CodeQL | | 依赖项扫描 | pip-audit | | 容器扫描 | Trivy | | DAST | OWASP ZAP Baseline Scan | | 依赖自动化 | Dependabot | | 本地安全检查 | pre-commit | | 云运行时 - AWS | EC2 | | 云运行时 - GCP | Cloud Run | | GCP 容器镜像仓库 | Artifact Registry | | GCP 构建 | Cloud Build | | GCP 日志 | Cloud Logging | | IaC 安全相关项目 | Terraform + Checkov | ## 每周进展与文档索引 本节是仓库的主要路线图。每周总结了已完成的安全工作,并链接到相关文档或证据文件。 | 周次 | 重点领域 | 完成内容 | 文档 / 证据 | |---|---|---|---| | 第 1 周 | DevSecOps 基础 | 构建 Flask API,对应用进行 Docker 化,添加 GitHub Actions CI、Gitleaks、Semgrep、pip-audit、Trivy,并修复了早期发现的问题。 | 主 README 部分:[CI/CD Pipeline](#cicd-pipeline)、[Security Gates](#security-gates)、[Security Reports and Observability](#security-reports-and-observability) | | 第 2 周 | CI/CD 加固 | 添加了基于分支的 PR 工作流、最小权限的 GitHub Actions 权限、工作流并发控制、阻断性安全门禁、CodeQL、Dependabot、pre-commit hooks 以及 Docker 非 root 加固。 | [GitHub Actions Hardening](#github-actions-hardening)、[CodeQL Code Scanning](#codeql-code-scanning)、[Dependabot Automation](#dependabot-automation)、[Shift-Left Security with pre-commit](#shift-left-security-with-pre-commit) | | 第 6 周 | OWASP ZAP DAST | 添加了针对正在运行的 Flask 容器的 OWASP ZAP Baseline Scan,生成了 HTML/Markdown/JSON 报告,上传了 artifacts,并添加了安全响应头以减少被动发现。 | [docs/week-6-dast-report.md](docs/week-6-dast-report.md) | | 第 7 周 | 容器安全 | 通过添加非 root 用户、所有权安全的拷贝行为以及容器运行时安全文档,加固了 Docker 的执行。 | [Security Finding and Remediation: Docker Running as Root](#security-finding-and-remediation-docker-running-as-root) | | 第 8 周 | 多云 IaC 安全 | 在单独的仓库中完成:针对 AWS 和 GCP 的 Terraform 安全基线、Checkov 扫描、CI 门禁以及修复证据。 | [Multi-Cloud IaC Security Scanning](https://github.com/AbdelazezMohamedAzez/multi-cloud-iac-security-scanning) | | 第 9 周 | 多云安全部署 | 添加了 AWS/GCP 安全部署规划、AWS EC2 实际部署、GCP Cloud Run 实际部署、运行时 Trivy 扫描、针对云 endpoint 的 ZAP 扫描、CI 与运行时扫描对比调查以及清理证据。 | [docs/week-9-multicloud-secure-deployment.md](docs/week-9-multicloud-secure-deployment.md)、[AWS Practical Evidence](docs/evidence/practical/aws-practical-deployment-evidence.md)、[GCP Practical Evidence](docs/evidence/practical/gcp-practical-deployment-evidence.md) | ## 文档导航 `docs/` 文件夹包含了每周总结背后的详细证据。 | 文件 | 用途 | |---|---| | [docs/week-6-dast-report.md](docs/week-6-dast-report.md) | 第 6 周 OWASP ZAP DAST 报告及运行时 Web 安全测试笔记 | | [docs/week-9-multicloud-secure-deployment.md](docs/week-9-multicloud-secure-deployment.md) | 第 9 周多云安全部署概述 | | [docs/evidence/aws-secure-deployment-evidence.md](docs/evidence/aws-secure-deployment-evidence.md) | AWS 安全部署规划证据 | | [docs/evidence/gcp-secure-deployment-plan.md](docs/evidence/gcp-secure-deployment-plan.md) | GCP 安全部署规划证据 | | [docs/evidence/aws-vs-gcp-security-comparison.md](docs/evidence/aws-vs-gcp-security-comparison.md) | AWS 与 GCP 安全性对比 | | [docs/evidence/week-9-final-evidence-checklist.md](docs/evidence/week-9-final-evidence-checklist.md) | 第 9 周最终证据核对清单 | | [docs/evidence/practical/aws-practical-deployment-evidence.md](docs/evidence/practical/aws-practical-deployment-evidence.md) | AWS EC2 + Docker 实际部署证据 | | [docs/evidence/practical/gcp-practical-deployment-evidence.md](docs/evidence/practical/gcp-practical-deployment-evidence.md) | GCP Cloud Run + Artifact Registry 实际部署证据 | ## 实际证据报告 第 9 周的实际报告存储在以下位置: ``` docs/evidence/practical/reports/ ``` 预期报告: ``` docs/evidence/practical/reports/ ├── trivy-week9-aws.txt ├── zap-week9-aws.html ├── zap-week9-aws.json ├── zap-week9-gcp.html └── zap-week9-gcp.json ``` 报告用途: | 报告 | 用途 | |---|---| | `trivy-week9-aws.txt` | 来自 AWS EC2 部署的运行时容器漏洞扫描 | | `zap-week9-aws.html` | 针对 AWS endpoint 的 OWASP ZAP HTML 报告 | | `zap-week9-aws.json` | 针对 AWS endpoint 的 OWASP ZAP JSON 报告 | | `zap-week9-gcp.html` | 针对 GCP Cloud Run endpoint 的 OWASP ZAP HTML 报告 | | `zap-week9-gcp.json` | 针对 GCP Cloud Run endpoint 的 OWASP ZAP JSON 报告 | ## 仓库结构 ``` . ├── .github/ │ └── workflows/ │ ├── security-ci.yml │ ├── codeql.yml │ └── zap-dast.yml ├── docs/ │ ├── week-6-dast-report.md │ ├── week-9-multicloud-secure-deployment.md │ └── evidence/ │ ├── aws-secure-deployment-evidence.md │ ├── gcp-secure-deployment-plan.md │ ├── aws-vs-gcp-security-comparison.md │ ├── week-9-final-evidence-checklist.md │ └── practical/ │ ├── aws-practical-deployment-evidence.md │ ├── gcp-practical-deployment-evidence.md │ └── reports/ │ ├── trivy-week9-aws.txt │ ├── zap-week9-aws.html │ ├── zap-week9-aws.json │ ├── zap-week9-gcp.html │ └── zap-week9-gcp.json ├── app.py ├── Dockerfile ├── requirements.txt ├── README.md └── .pre-commit-config.yaml ``` ## 本地运行 安装依赖项: ``` pip install -r requirements.txt ``` 运行应用程序: ``` python app.py ``` 然后打开: ``` http://localhost:5000 ``` ## 使用 Docker 运行 构建 Docker 镜像: ``` docker build -t secure-devsecops-starter . ``` 运行容器: ``` docker run -p 5000:5000 secure-devsecops-starter ``` 然后打开: ``` http://localhost:5000 ``` ## CI/CD 流水线 GitHub Actions pipeline 会在 push 和针对受保护分支的 pull request 时运行。 当前的工作流触发器: ``` push → main, develop pull_request → main, develop manual workflow_dispatch ``` 主要安全 pipeline 阶段: 1. 检出源代码 2. 准备安全报告目录 3. 运行 Gitleaks secret 扫描 4. 运行 Semgrep SAST 扫描 5. 使用 pip-audit 进行 Python 依赖项审计 6. 构建 Docker 镜像 7. 运行 Trivy 容器镜像扫描 8. 将安全报告作为 artifacts 上传 9. 编写安全摘要 10. 强制执行最终安全门禁 OWASP ZAP DAST 工作流阶段: 1. 检出源代码 2. 构建 Docker 镜像 3. 运行 Flask 应用程序容器 4. 等待 `/health` endpoint 5. 针对正在运行的应用程序执行 OWASP ZAP Baseline Scan 6. 将 ZAP 报告作为 GitHub Actions artifacts 上传 7. 停止并移除应用程序容器 DAST 工作流在运行时验证应用程序,而不是仅仅扫描源文件或依赖项。 ## GitHub Actions 加固 工作流使用最小权限进行了加固: ``` permissions: contents: read pull-requests: read security-events: write actions: read ``` 还添加了并发控制,以防止在同一分支上重复运行工作流: ``` concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true ``` 这改善了 pipeline 控制,减少了嘈杂的运行,并遵循了更像生产环境的 GitHub Actions 设置。 ## 安全门禁 该 pipeline 使用安全门禁在合并前阻止不安全的更改。 | 门禁 | 工具 | 阻断条件 | |---|---|---| | Secrets 门禁 | Gitleaks | 检测到 secret 或凭据 | | SAST 门禁 | Semgrep | 检测到 ERROR 级别的 SAST 发现 | | 依赖项门禁 | pip-audit | 检测到有漏洞的 Python 依赖项 | | 容器门禁 | Trivy | 检测到 HIGH 或 CRITICAL 漏洞 | | 构建门禁 | Docker | Docker 镜像构建失败 | | 运行时门禁 | ZAP 设置 | 应用程序容器无法启动 | 最后的强制执行步骤会检查每个安全阶段的结果,如果有任何阻断性门禁失败,则 pipeline 会失败。 OWASP ZAP Baseline Scan 目前用作 DAST 证据和分类步骤。它将报告作为 artifacts 上传,以便对发现的问题进行审查和修复。 ## 安全报告与可观测性 安全报告将生成并作为 GitHub Actions artifacts 上传。 生成的 CI 报告包括: ``` reports/ ├── semgrep.json ├── pip-audit.json └── trivy.txt zap-reports/ ├── zap-report.html ├── zap-report.md └── zap-report.json ``` 这些报告为以下方面提供了证据: - 安全审查 - 调试失败的 pipeline - 漏洞分类 - DAST 发现审查 - 运行时验证 - 云部署证据 - 面试演示 - 作品集文档 ## 安全发现与修复:Flask 开发服务器 Semgrep 检测到 Flask 开发服务器正在使用: ``` app.run(host="0.0.0.0", port=5000) ``` 这可能会将开发服务器公开暴露。 该问题通过将其更改为以下内容得到了修复: ``` app.run(host="127.0.0.1", port=5000, debug=False) ``` 修复后,GitHub Actions pipeline 成功通过。 ## 安全发现与修复:Docker 以 Root 身份运行 在 pipeline 加固期间,Semgrep 检测到 Docker 容器没有指定非 root 用户。 发现: ``` dockerfile.security.missing-user.missing-user ``` 风险: 如果攻击者攻破了应用程序进程,以 root 身份运行容器会增加容器环境内部的破坏影响。 已应用的修复: ``` RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser COPY --chown=appuser:appgroup . . USER appuser ``` 修复后,pipeline 成功通过。 ## Secret 扫描测试 使用自定义的演示规则对 Gitleaks 进行了测试。 在一个单独的测试分支上故意提交了一个演示 secret,以验证 secret 扫描是否有效。 结果: - Gitleaks 检测到了演示 secret - pipeline 按预期失败 - 演示 secret 已被移除 - 修复后 pipeline 再次通过 这证实了 secret 扫描正作为阻断性 CI 门禁发挥作用。 ## 使用 pip-audit 进行依赖项扫描 添加了 pip-audit 以扫描 `requirements.txt` 中的 Python 依赖项。 它检测到了 Flask 3.0.3 中的一个漏洞,并建议升级 Flask。 该问题通过将 Flask 更新到 3.1.3 版本得到了修复: ``` Flask==3.1.3 gunicorn==22.0.0 ``` 升级后,GitHub Actions pipeline 成功通过。 ## 使用 Trivy 进行容器扫描 添加了 Trivy 以扫描 Docker 镜像中的 HIGH 和 CRITICAL 漏洞。 该 pipeline 会构建 Docker 镜像并在认为 CI 成功之前对其进行扫描。 当前 Trivy CI 行为: - 扫描构建好的 Docker 镜像 - 检查 HIGH 和 CRITICAL 漏洞 - 忽略未修复的漏洞 - 当检测到阻断性漏洞时使 pipeline 失败 第 9 周增加了一个重要的运行时验证教训: - GitHub Actions 通过了,因为 Trivy CI 扫描配置了 `ignore-unfixed: true`。 - AWS 运行时扫描在没有 `--ignore-unfixed` 的情况下执行了。 - 运行时 Trivy 扫描识别出了在 CI 结果中不可见的基础镜像漏洞。 - 这些发现与 Debian 基础镜像包有关,而不是 Python 应用程序依赖项。 - 在 AWS 运行时 Trivy 报告中,Python 包显示 `0` 个漏洞。 这表明扫描配置会影响可见性,并且通过的 CI 应该有运行时验证和证据审查作为支撑。 ## 使用 OWASP ZAP 进行动态应用程序安全测试 添加了 OWASP ZAP Baseline Scan 以动态测试正在运行的 Flask 应用程序。 ZAP 工作流: 1. 构建 Docker 镜像 2. 运行应用程序容器 3. 等待 `/health` endpoint 4. 针对 `http://127.0.0.1:5000` 运行 OWASP ZAP Baseline Scan 5. 生成 HTML、Markdown 和 JSON 报告 6. 将报告作为 GitHub Actions artifacts 上传 这为项目增加了运行时 Web 安全测试。 该扫描未经身份验证且侧重于被动检查,这使其适合作为早期的 CI/CD DAST 检查。 第 6 周报告: ``` docs/week-6-dast-report.md ``` 第 9 周实际的云 ZAP 报告: ``` docs/evidence/practical/reports/zap-week9-aws.html docs/evidence/practical/reports/zap-week9-aws.json docs/evidence/practical/reports/zap-week9-gcp.html docs/evidence/practical/reports/zap-week9-gcp.json ``` ## CodeQL 代码扫描 添加了 CodeQL 作为额外的静态代码分析层。 CodeQL 提供了更深入的代码扫描,并与 GitHub Security 功能集成。 当前 CodeQL 设置: - 在 pull request 时运行 - 在 push 到受保护分支时运行 - 扫描 Python 代码 - 使用 security-extended 和 security-and-quality 查询 结果出现在: ``` GitHub → Security → Code scanning ``` ## Dependabot 自动化 添加了 Dependabot 以自动化依赖项和工作流更新检查。 已配置的生态系统: | 生态系统 | 用途 | |---|---| | pip | 监控 Python 依赖项 | | github-actions | 监控 GitHub Actions 版本 | | docker | 监控 Docker 基础镜像更新 | Dependabot 通过开启自动更新的 pull request 来帮助保持项目最新,并降低供应链风险。 ## 使用 pre-commit 实现左移安全 添加了本地 pre-commit 层,以便在代码到达 GitHub 之前发现问题。 当前 pre-commit hooks: | Hook | 用途 | |---|---| | detect-private-key | 防止提交私钥 | | check-yaml | 验证 YAML 文件 | | check-json | 验证 JSON 文件 | | end-of-file-fixer | 确保文件正确结尾 | | trailing-whitespace | 删除不必要的空格 | | Gitleaks | 在本地检测硬编码的 secret | 手动运行所有 hooks: ``` pre-commit run --all-files ``` 在本地安装 hooks: ``` pre-commit install ``` 这在 CI/CD 之前增加了一个本地安全层。 ## 第 9 周:多云实际安全部署 第 9 周将项目从 CI/CD 安全扩展到了实际的云部署证据。 目标不是让生产基础设施保持运行。目标是进行临时部署,验证安全控制,收集证据,并清理所有资源。 ### AWS 实际部署 AWS 使用了基于 VM 的部署模型: ``` EC2 → Docker → Flask container ``` 已完成的 AWS 工作: - 创建了临时的 EC2 实例 - 将 Security Group 访问限制为我的 IP - 在 EC2 上安装了 Docker - 构建了 Docker 镜像 - 在端口 `5000` 上运行 Flask 容器 - 在浏览器中和使用 curl 验证了应用程序 - 在 EC2 主机上安装并运行了 Trivy - 保存了 Trivy 运行时扫描报告 - 针对 AWS endpoint 运行了 OWASP ZAP baseline scan - 保存了 ZAP HTML 和 JSON 报告 - 调查了为什么 GitHub Actions 没有显示相同的 Trivy 发现 - 停止并移除了容器 - 终止了 EC2 实例 - 测试后移除了临时的 AWS 资源 AWS 证据: ``` docs/evidence/practical/aws-practical-deployment-evidence.md docs/evidence/practical/reports/trivy-week9-aws.txt docs/evidence/practical/reports/zap-week9-aws.html docs/evidence/practical/reports/zap-week9-aws.json ``` ### GCP 实际部署 GCP 使用了托管式 serverless 容器部署模型: ``` Artifact Registry → Cloud Run → HTTPS endpoint ``` 已完成的 GCP 工作: - 启用了所需的 GCP API - 创建了 Artifact Registry Docker 仓库 - 使用 Cloud Shell / Cloud Build 构建并推送了镜像 - 将镜像部署到 Cloud Run - 暂时允许了公开访问以进行测试 - 使用了基于请求的计费 - 将最小实例数设置为 `0` - 将最大实例数设置为 `1` - 打开并验证了 Cloud Run URL - 查看了 Cloud Run 日志 - 针对 GCP endpoint 运行了 OWASP ZAP baseline scan - 保存了 ZAP HTML 和 JSON 报告 - 删除了 Cloud Run 服务 - 删除了 Artifact Registry 仓库 - 确认完成了 GCP 清理 GCP 证据: ``` docs/evidence/practical/gcp-practical-deployment-evidence.md docs/evidence/practical/reports/zap-week9-gcp.html docs/evidence/practical/reports/zap-week9-gcp.json ``` ### AWS 与 GCP 部署模型对比 | 领域 | AWS 实际 | GCP 实际 | |---|---|---| | 运行时 | EC2 VM | Cloud Run | | 容器执行 | 安装在 VM 上的 Docker | 托管式容器运行时 | | 镜像存储 | 在 EC2 上本地构建 | Artifact Registry | | 网络暴露 | Security Group 规则 | Cloud Run 公开访问设置 | | DAST | 针对 EC2 endpoint 的 ZAP | 针对 Cloud Run URL 的 ZAP | | 日志 | 运行时和 EC2 验证 | Cloud Logging | | 清理 | 终止 EC2 并移除临时资源 | 删除 Cloud Run 服务和 Artifact Registry 仓库 | 这演示了传统的基于 VM 的部署和托管式 serverless 容器部署。 ## 当前状态 该项目目前具有: - 在本地运行的 Flask 应用 - 正常工作的 Docker 构建 - 使用非 root 用户的加固 Dockerfile - 配置了基础的 Flask 安全响应头 - 正常工作的 GitHub Actions CI pipeline - 配置了最小权限的工作流权限 - 已配置并测试的 Gitleaks - 已配置并测试的 Semgrep - 已配置并测试的 pip-audit - 已配置并测试的 Trivy - 已配置并通过的 CodeQL - 已配置的 Dependabot - 已配置并在本地测试的 pre-commit - 添加了 OWASP ZAP DAST 工作流 - 作为 artifacts 上传的安全报告 - 作为 artifacts 上传的 ZAP DAST 报告 - 修复了真实的 Semgrep 发现 - 修复了真实的依赖项漏洞 - 修复了真实的容器加固发现 - 通过的安全门禁 - 完成了 AWS 实际安全部署证据 - 完成了 GCP 实际 Cloud Run 部署证据 - 记录了运行时 Trivy 扫描证据 - 记录了 CI 与运行时扫描行为 - 收集了 AWS 和 GCP ZAP 报告 - 清理了 AWS 和 GCP 临时资源 ## 我学到了什么 - 如何使用最小权限来加固 GitHub Actions - 如何将安全工具从被动的报告转化为阻断性的 CI 门禁 - 如何分析和修复真实的 SAST 发现 - 如何防止容器以 root 身份运行 - 如何将安全扫描报告作为 pipeline artifacts 上传 - 如何使用 CodeQL 进行 GitHub 原生代码扫描 - 如何使用 Dependabot 自动化依赖项更新 - 如何使用 pre-commit hooks 实现左移安全 - 如何针对实时的容器化应用程序运行 OWASP ZAP DAST - 如何在运行时安全扫描之前使用 `/health` 检查 - 如何将安全发现和修复记录为作品集证据 - 如何在 AWS EC2 上部署 Docker 化的应用程序 - 如何在 GCP Cloud Run 上部署 Docker 化的应用程序 - 如何使用 Artifact Registry 进行容器镜像存储 - 如何比较基于 VM 的和托管式容器部署模型 - 扫描器配置如何隐藏或揭示漏洞发现 - 如何记录测试后的临时云资源清理 ## 后续改进 计划的后续步骤: - 使用 Syft 添加 SBOM 生成 - 使用 Cosign 添加容器镜像签名 - 添加基于 OIDC 的云部署 - 使用轻量级的本地或托管集群添加 Kubernetes 安全实验 - 添加云审计日志截图和检测笔记 - 为常见的云发现添加事件响应 runbook - 添加 CSPM 式的云错误配置审查清单 - 添加带有安全回滚文档的自动化部署 ## 相关安全项目 - [Multi-Cloud IaC Security Scanning](https://github.com/AbdelazezMohamedAzez/multi-cloud-iac-security-scanning) ## 作品集价值 该仓库展示了实用的 DevSecOps 和云安全工程师技能: - 安全的 CI/CD pipeline 设计 - 安全门禁和自动化 - SAST、SCA、secret 扫描、容器扫描和 DAST - Docker 加固 - 运行时漏洞调查 - AWS 安全部署证据 - GCP Cloud Run 部署证据 - 云清理规范 - 专业的安全文档
标签:DevSecOps, Docker, Python Flask, Web安全, 上游代理, 安全防御评估, 蓝队分析, 请求拦截, 逆向工具