S1YOL/portcullis

GitHub: S1YOL/portcullis

Portcullis 是一个零依赖的 PR 安全门禁工具,在代码审查阶段拦截密钥泄露、依赖项 CVE 和 IaC/CI 配置错误。

Stars: 0 | Forks: 0

# Portcullis **一个用于 pull request 的左移安全门禁。** Portcullis 会扫描每个 PR,查找硬编码的 **secrets**、**易受攻击的依赖项**以及**基础设施 / CI 配置错误**,将扫描结果发布回 PR,将其作为 SARIF 上传至 GitHub 的 **Security tab**,并在超过您设定的严重性阈值时**使构建失败** —— 从而确保问题在代码审查中被发现,而不是遗留到生产环境中。

CI Python Runtime deps Output License

## 为什么需要 大多数团队发现安全问题的途径通常都不太理想:要么是没人看的扫描器报告,要么是发生了安全事件。Portcullis 将检查环节放在**开发者已经在的地方** —— pull request —— 并使其成为一个**门禁**,而不仅仅是建议。 - **Secrets** - git 历史记录中泄露的密钥就像一颗随时引爆的定时炸弹。 - **依赖项** - 大多数被利用的漏洞都是第三方包中已知的 CVE。 - **IaC / CI** - 使用 `pull_request_target` 检出 fork 代码,或者将 security group 开放给 `0.0.0.0/0`,是导致 pipeline 和云账户被接管的常见原因。 只需一个 action 即可涵盖这三个方面,并且**零运行时依赖**(纯 Python 标准库 —— 无需 pip install,自身也没有供应链攻击面)。 ## 检查内容 | 领域 | 示例 | 判定依据 | |---|---|---| | **Secrets** | AWS / GitHub / Slack / Google / Stripe token、私钥、JWT,以及通用的针对高熵特征的扫描 | 精心维护的正则表达式 + Shannon 熵 | | **依赖项 (SCA)** | `requirements.txt`、`package.json`、`go.mod` 锁定版本中的已知 CVE | 免费的 [OSV.dev](https://osv.dev) API - 无需密钥 | | **IaC / CI** | `curl \| sh`、root container、未锁定的 action、`pull_request_target` 检出、脚本注入、开放的 security group、通配符 IAM | 内置规则集 | 完整规则参考:[`docs/rules.md`](docs/rules.md)。 **实时 secret 验证。** 在 `verify-secrets: true` 模式下运行时,Portcullis 会确认检测到的 token 是否*当前实际有效*(例如 GitHub PAT)。经验证有效的 secret 将被升级为 **Critical** 级别 —— 这不再是疑似泄漏,而是确实发生了泄漏。 ## 快速开始 (GitHub Action) 添加 `.github/workflows/security.yml`: ``` name: Security on: [pull_request] permissions: contents: read pull-requests: write # PR comment security-events: write # SARIF upload jobs: portcullis: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - id: scan uses: S1YOL/portcullis@v1 continue-on-error: true # let SARIF upload even when the gate fails with: fail-on: high verify-secrets: 'true' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: portcullis.sarif category: portcullis - if: steps.scan.outputs.blocked == 'true' run: exit 1 # enforce the gate ``` 就是这样。在下一个 PR 中,您将获得 diff 上的内联注释、总结性评论、**Security** tab 中的警报,以及如果超过阈值时显示的失败检查。 ## 快速开始 (CLI) ``` # 无需安装 - 它是 standard-library Python。 python -m portcullis path/to/repo --fail-on high --sarif results.sarif # 只有一个 scanner,并验证它发现的任何 secrets 是否为 live: python -m portcullis . --only secrets --verify-secrets # 仅生成报告(从不会导致 build 失败): python -m portcullis . --fail-on none ``` 当门禁通过时退出代码为 `0`,阻断时为 `1` —— 因此它可以直接接入任何 CI 系统,而不仅限于 GitHub。 ## 示例 针对内置的 [`examples/vulnerable-sample`](examples/vulnerable-sample) 运行: ``` Portcullis - scan results ---------------------------------------------- Critical 3 High 11 Medium 13 Low 1 ---------------------------------------------- Total: 28 finding(s) [CRIT] pyyaml 5.1 - CVE-2020-1747 requirements.txt:2 [HIGH] GitHub Personal Access / App Token app_config.py:11 [HIGH] pull_request_target checks out untrusted PR code .github/workflows/ci.yml:5 [HIGH] Security group open to the entire internet main.tf:10 ... Portcullis gate: 14 finding(s) at or above 'High' - failing the build. ``` ## 配置 | 输入项 | 默认值 | 描述 | |---|---|---| | `path` | `.` | 要扫描的目录。 | | `fail-on` | `high` | 导致构建失败的最低严重级别:`critical`/`high`/`medium`/`low`/`none`。 | | `only` | *(全部)* | 逗号分隔的子集:`secrets,deps,iac`。 | | `verify-secrets` | `false` | 在支持的场景下对检测到的 secret 进行实时验证。 | | `sarif-file` | `portcullis.sarif` | 写入 SARIF 2.1.0 的位置。 | | `comment-pr` | `true` | 在 PR 上发布/更新结果评论。 | 输出项:`findings`(计数)和 `blocked`(`true`/`false`)。 ## 工作原理 ``` manifests / source tree | |-- secrets : regex + entropy (+ optional live verification) |-- deps : parse pins -> OSV.dev -> known CVEs |-- iac : curated Dockerfile / GitHub Actions / Terraform rules | v findings --> SARIF 2.1.0 --> GitHub code scanning (Security tab) --> Markdown --> PR comment + Actions step summary --> policy gate --> exit code (pass / fail) ``` 所有内容都共享同一个 `Finding` 模型,因此添加扫描器或规则只是一个局部的微小改动。 ## 开发说明 ``` pip install -r requirements-dev.txt ruff check portcullis/ tests/ --select E,F,W --ignore E501,E402 python -m pytest tests/ -v ``` Portcullis 会进行自我测试:[`.github/workflows/security.yml`](.github/workflows/security.yml) 会在本仓库中运行此 action。 ## 关联项目 Portcullis 是应用安全的**左移 / 静态**部分。它的兄弟项目 [**W3BSP1D3R**](https://github.com/S1YOL/W3BSP1D3R) 则是**运行时 / DAST**部分 —— 这是一个用于攻击实时应用以发现漏洞的 Web 漏洞扫描器。它们共同涵盖了整个 SDLC 的安全:在 PR 中拦截问题,*并在*运行时进行验证。 ## 许可证 MIT - 查看 [LICENSE](LICENSE)。
标签:DevSecOps, Python, StruQ, 上游代理, 代码安全, 文档安全, 无后门, 漏洞枚举, 逆向工具, 静态应用安全测试