chrisgillham/oss-trust-framework

GitHub: chrisgillham/oss-trust-framework

一个多重关卡的开源供应链信任验证框架,用于在依赖更新进入应用前进行安全审查并拦截恶意包,同时为零日漏洞补丁提供受控快速通道。

Stars: 1 | Forks: 0

# OSS 信任框架 [![PyPI](https://img.shields.io/pypi/v/oss-trust-framework?color=blue&label=PyPI)](https://pypi.org/project/oss-trust-framework/) [![Python](https://img.shields.io/pypi/pyversions/oss-trust-framework)](https://pypi.org/project/oss-trust-framework/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) **开源供应链信任验证流水线** 一个多重关卡的安全框架,用于在开源依赖项更新到达您的应用程序之前对其进行验证——针对 CI/CD 流水线入侵(Miasma、Shai-Hulud、TanStack、Bitwarden、IronWorm)提供坚固的防御,并为零日漏洞 CVE 补丁提供严格控制的快速通道。 ## 目录 - [安装](#installation) - [使用指南](#usage-guide) - [检查项目中的所有依赖](#1-check-all-deps-in-a-project-the-most-common-task) - [检查单个包](#2-check-a-single-package) - [Windows 用户](#3-windows-users) - [CI/CD 集成](#4-cicd-integration) - [零日快速通道](#5-zero-day-expedited-lane) - [填充可信发布者白名单](#6-populate-the-trusted-publishers-allowlist) - [支持的生态系统](#supported-ecosystems) - [配置](#configuration) - [为何开发此框架](#why-this-exists) - [架构](#architecture) - [关卡参考](#gate-reference) - [攻击覆盖范围](#attack-coverage) - [运行测试](#running-tests) - [贡献](#contributing) ## 安装 ``` pip install oss-trust-framework # 验证 oss-trust --version # oss-trust, 版本 0.6.1 ``` ## 使用指南 ### 1. 检查项目中的所有依赖(最常见任务) **npm 项目:** ``` oss-trust check-all --manifest package.json ``` **Python 项目(自动检测 `requirements.txt`):** ``` oss-trust check-all ``` **Rust:** ``` oss-trust check-all --manifest Cargo.toml ``` **Ruby:** ``` oss-trust check-all --manifest Gemfile.lock ``` **.NET:** ``` oss-trust check-all --manifest packages.config ``` **一次性检查多个清单(混合技术栈项目):** ``` oss-trust check-all --manifest package.json --manifest requirements.txt ``` **跳过开发依赖(仅检查生产环境):** ``` oss-trust check-all --prod-only ``` **非交互模式 — 用于 CI 流水线:** ``` oss-trust check-all --manifest package.json --no-interactive ``` **JSON 输出 — 用于 CI 流水线和报告:** ``` # Linux/Mac oss-trust check-all --manifest package.json --no-interactive --output json > trust-report.json # Windows PowerShell (重定向需要 UTF-8 编码) $env:PYTHONUTF8 = "1" oss-trust check-all --manifest package.json --no-interactive --output json 2>$null > trust-report.json ``` **如果任何包处于 HOLD(挂起)状态则使构建失败:** ``` oss-trust check-all --manifest package.json --no-interactive --fail-on-hold ``` **输出效果如下:** ``` OSS Trust Framework - check-all config: ./config/trusted_publishers.yaml package.json -> 9 packages Running Gate 1 age checks on 9 packages... All packages are in the trusted_publishers allowlist. Ecosystem Package Version Allowlist Age (h) Gate 1 Outcome npm express 4.18.2 check 32261.3 pass PASS npm jsonwebtoken 9.0.2 check 24445.0 pass PASS npm uuid 14.0.0 check 168.2 pass PASS ... Summary: 9 packages -- 9 passed 0 on hold 0 blocked 0 errors ``` **JSON 输出(`trust-report.json`)效果如下:** ``` [ { "ecosystem": "npm", "package": "express", "version": "4.18.2", "source": "package.json", "in_allowlist": true, "attestation_required": false, "age_hours": 32261.3, "gate1_decision": "pass", "gate1_message": "express@4.18.2 is 32261.3h old -- age gate cleared.", "outcome": "PASS" } ] ``` ### 2. 检查单个包 当您想在升级前验证某个特定的包版本时使用此命令——尤其是在执行 `npm audit fix --force` 或处理 Dependabot PR 之后非常有用。 ``` # 基本检查 — 仅 Gate 1 (age) oss-trust check --package express --version 5.0.0 --ecosystem npm # 完整 pipeline 检查 — 所有 gates,包括 provenance 和 OOB trust oss-trust check \ --package requests \ --version 2.33.0 \ --ecosystem PyPI \ --github-repo psf/requests # 带有 GitHub repo 的 npm package 以实现完整的 gate 覆盖 oss-trust check \ --package jsonwebtoken \ --version 9.0.2 \ --ecosystem npm \ --github-repo auth0/node-jsonwebtoken # Cargo crate oss-trust check --package serde --version 1.0.200 --ecosystem Cargo # Maven artifact (使用 groupId:artifactId 格式) oss-trust check \ --package "org.apache.commons:commons-lang3" \ --version 3.14.0 \ --ecosystem Maven ``` **支持的 `--ecosystem` 取值:** `PyPI` `npm` `Cargo` `Go` `Maven` `NuGet` `RubyGems` **PASS(通过)效果如下:** ``` Gate 1 (Age): PASS — requests@2.33.0 is 1847.2h old Gate 2 (Provenance): PASS — published from psf/requests (expected) Gate 3 (OOB Trust): PASS — score 82.5/100, 0 active CVEs Outcome: APPROVED ``` **BLOCK(阻断)效果如下(新发布版本):** ``` Gate 1 (Age): BLOCK — express@5.0.1 is 4.2h old Hard block threshold is 24h. File a CVE reference to route through the zero-day expedited lane. Outcome: BLOCKED ``` **HOLD(暂扣)效果如下(24-72小时时间窗口):** ``` Gate 1 (Age): HOLD — cryptography@44.0.1 is 31.5h old Within the 72h hold window. Human approval required. Outcome: HOLD ``` ### 3. Windows 用户 PowerShell 重定向(`>`)默认使用 cp1252 编码,该编码无法处理 Rich 终端输出中的某些 Unicode 字符。请先设置 UTF-8 模式: ``` # 对于当前 session $env:PYTHONUTF8 = "1" # 使其永久生效 (运行一次) New-Item -ItemType Directory -Force -Path (Split-Path $PROFILE) Add-Content $PROFILE "`n`$env:PYTHONUTF8 = '1'" ``` **在将输出保存到文件时,请将 stderr 从 JSON 输出中重定向出去**(Rich 表格输出到 stderr,JSON 输出到 stdout): ``` # 仅保存 JSON,隐藏表格显示 oss-trust check-all --manifest package.json --output json 2>$null > trust-report.json # 查看 JSON 报告 Get-Content trust-report.json | ConvertFrom-Json | Format-Table ecosystem, package, version, outcome ``` ### 4. CI/CD 集成 **GitHub Actions — 在 lock 文件发生任何更改时自动运行:** 将 `.github/workflows/dep-trust-check.yml` 添加到您的仓库中: ``` name: Dependency trust check on: pull_request: paths: - '**/package.json' - '**/package-lock.json' - '**/requirements.txt' - '**/Cargo.toml' - '**/Cargo.lock' - '**/Gemfile.lock' jobs: trust-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install OSS Trust Framework run: pip install oss-trust-framework - name: Run trust check run: | oss-trust check-all \ --manifest package.json \ --no-interactive \ --fail-on-hold \ --output json > trust-report.json - name: Upload trust report uses: actions/upload-artifact@v4 with: name: trust-report path: trust-report.json ``` **退出码:** | 代码 | 含义 | |------|---------| | `0` | 所有包均已通过 | | `1` | 一个或多个包被 BLOCKED(阻断)或(使用 `--fail-on-hold` 时)被 HELD(暂扣) | | `2` | 未找到任何需要检查的包 | ### 5. 零日快速通道 当您依赖的包发布了合法的零日漏洞补丁时,72 小时的发布时间暂扣规则就会产生时间差。快速通道**仅**绕过年限关卡(Age Gate)——所有其他关卡依然是强制性的。 **第 1 步 — 请求例外:** ``` oss-trust zeroday request \ --cve CVE-2024-12345 \ --package cryptography \ --version 44.0.1 \ --ecosystem PyPI \ --requester security@yourorg.com ``` 输出: ``` CVE-2024-12345 validated against NVD + OSV + GHSA (2-of-3 sources required) Quorum request created: request-id abc123def456 Notify approvers: approver_001, approver_002, approver_003 Token TTL: 6 hours ``` **第 2 步 — 每位审批者单独审批(需要 MFA):** ``` oss-trust zeroday approve \ --request-id abc123def456 \ --approver-id approver_001 \ --mfa-token 123456 ``` **第 3 步 — 检查状态:** ``` oss-trust zeroday status --request-id abc123def456 ``` **规则:** - 请求者不能批准自己的请求(职责分离) - 需要 3 名指定审批者中的 2 名同意 - Token 在 6 小时后过期 — 不予延期 - 24 小时内超过 3 次例外请求将暂停快速通道,等待 CISO 审查 ### 6. 填充可信发布者白名单 白名单将包名映射到其标准的 GitHub 源代码仓库。关卡 2 使用此信息来验证包的来源出处证明是否指向正确的仓库——而不是被入侵的分支或员工账户(Miasma 攻击模式)。 **交互式填充 — 任何项目推荐的第一步:** ``` # 从您的项目目录运行 oss-trust check-all --manifest package.json ``` 对于不在白名单中的任何包,系统会提示您: ``` express@4.18.2 is not in trusted_publishers.yaml Looking up canonical repo... found: expressjs/express [1] Add to allowlist only [2] Add to allowlist + require_attestation (block if no Sigstore attestation) [s] Skip [q] Quit interactive mode Choice [1/2/s/q]: 1 Added npm/express: expressjs/express config/trusted_publishers.yaml saved. ``` **无提示自动填充(脚本/自动化):** ``` # 在 scripts/check_all.py 中 — 为 manifest 中的所有 deps 输出 YAML 条目 python scripts/check_all.py --populate-allowlist npm package.json ``` 输出: ``` # npm trusted_publishers 条目 # 从 package.json 生成 "express": "expressjs/express" "jsonwebtoken": "auth0/node-jsonwebtoken" "helmet": "helmetjs/helmet" # "acme-client": "FIXME/repo" <-- couldn't auto-resolve, fill in manually ``` 粘贴到 `config/trusted_publishers.yaml` 的 `npm:` 部分下。 **手动编辑 `config/trusted_publishers.yaml`:** ``` npm: "express": "expressjs/express" "jsonwebtoken": "auth0/node-jsonwebtoken" "uuid": "uuidjs/uuid" PyPI: "cryptography": "pyca/cryptography" "requests": "psf/requests" Cargo: "serde": "serde-rs/serde" "tokio": "tokio-rs/tokio" require_attestation: # These packages BLOCK if no Sigstore attestation found PyPI: - "cryptography" - "requests" npm: - "jsonwebtoken" ``` ## 支持的生态系统 ### 全关卡覆盖 | 生态系统 | Registry | 包格式 | 示例 | 清单 | |-----------|----------|----------------|---------|----------| | `PyPI` ✅ | pypi.org | `package==version` | `requests==2.33.0` | `requirements.txt` | | `npm` ✅ | npmjs.com | `package@version` | `express@4.18.2` | `package.json` | ### 部分覆盖(关卡 0、1、2.5、3、4 — 关卡 2 来源出处证明待定) | 生态系统 | Registry | 包格式 | 示例 | 清单 | 关卡 2 状态 | |-----------|----------|----------------|---------|----------|--------------| | `Cargo` | crates.io | `crate@version` | `serde@1.0.200` | `Cargo.toml` | ⚠️ 占位符 — 计划集成 `cargo-vet` | | `RubyGems` | rubygems.org | `gem` | `rails` | `Gemfile.lock` | ❌ 尚未实现 | | `NuGet` | nuget.org | `PackageId` | `Newtonsoft.Json` | `packages.config` | ❌ 尚未实现 | ### 仅清单解析器和年限检查(关卡 0、1、3 — 无 lockfile 解析器或关卡 2) | 生态系统 | Registry | 包格式 | 示例 | 清单 | 缺失功能 | |-----------|----------|----------------|---------|----------|----------------| | `Go` | proxy.golang.org | module path | `github.com/gin-gonic/gin` | ❌ 需要解析 `go.sum` | Manifest 解析器、关卡 2(GOPROXY 校验和数据库) | | `Maven` | search.maven.org | `groupId:artifactId` | `org.apache.commons:commons-lang3` | ❌ 需要解析 `pom.xml` / `build.gradle` | Manifest 解析器、关卡 2(通过 Maven Central 的 GPG) | 对于通过 `--manifest` 或通过 `framework_deps.txt` 前缀格式(`Go:github.com/gin-gonic/gin@v1.9.0`)明确指定的 Go 和 Maven 包,仍然可以运行关卡 0、1、3 和 4。 | 文件 | 生态系统 | 是否支持? | |------|-----------|-----------| | `requirements.txt` | PyPI | ✅ 自动检测 | | `framework_deps.txt` | Multi | ✅ 自动检测 | | `package.json` | npm | ✅ 传递 `--manifest package.json` | | `Cargo.toml` | Cargo | ✅ 传递 `--manifest Cargo.toml` | | `Gemfile.lock` | RubyGems | ✅ 传递 `--manifest Gemfile.lock` | | `packages.config` | NuGet | ✅ 传递 `--manifest packages.config` | | `go.sum` / `go.mod` | Go | ❌ 尚不支持 | | `pom.xml` / `build.gradle` | Maven | ❌ 尚不支持 | **尚不支持**(路线图请参阅 [BACKLOG.md](BACKLOG.md)): `poetry.lock` · `pyproject.toml` · `uv.lock` · `Pipfile.lock` · `Cargo.lock` · `packages.lock.json` · `*.csproj` · `pub.yaml` (Dart) · `Package.swift` · `composer.lock` (PHP) ## 配置 ### `config/pipeline.yaml` — 关卡阈值 ``` age_gate: hard_block_hours: 24 # Releases younger than this: auto-blocked hold_hours: 72 # 24-72h: human approval required before proceeding trust_scoring: min_scorecard_score: 6.0 # OpenSSF Scorecard minimum (0-10 scale) require_zero_active_vulns: true cicd_audit: orphan_commits: enabled: true action_on_orphan: block workflow_permissions: enabled: true action_on_finding: quarantine pr_provenance: min_pr_reviewers: 1 action_on_direct_push: block sandbox: runtime: gvisor # gvisor | strace | audit network: none behavioral_patterns: block_on_critical: true zero_day: required_approvers: 2 token_ttl_hours: 6 circuit_breakers: max_exceptions_per_24h: 3 ``` ### `config/trusted_publishers.yaml` — 基于包的白名单 请参阅上方的 [填充可信发布者白名单](#6-populate-the-trusted-publishers-allowlist)。涵盖所有 7 个生态系统中 100 多个高价值包的完整预填充白名单随框架一起提供,位于 `config/trusted_publishers.yaml`。 ## 为何开发此框架 目前有三种截然不同的供应链攻击模式正在突破传统的防御手段: **模式 2 — CI/CD 流水线入侵(Miasma 类)。** 攻击者入侵合法员工的 GitHub 账户,推送绕过 PR 审查的孤立提交(orphan commits),并利用 `id-token: write` CI/CD 权限通过 OIDC 受信任发布机制进行发布。这些包被*正确签名*——签名是真实的。传统的签名验证完全通过。 ### 活跃攻击 | 攻击 | 日期 | 包 | 攻击向量 | 状态 | |---|---|---|---|---| | **Miasma / Red Hat Insights** | 2026 | 32 npm | 被入侵的员工账户 + OIDC 受信任发布 | 活跃攻击活动 | | **IronWorm** | 2026-06-03 | 36 npm | Rust ELF preinstall hook + eBPF rootkit + Tor C2 | 活跃攻击活动 | | **TanStack** | 2026 | 170 npm | 相同的 OIDC 受信任发布模式 | 活跃攻击活动 | | **Bitwarden CLI** | 2026 | npm | Checkmarx 活动 — OIDC 受信任发布 | 活跃攻击活动 | | **XZ Utils** | 2024 | tarball | 2年期的社会工程学 -> 构建脚本后门 | CVSS 10.0 | ## 架构 ``` Dependency update request | v +----------------------+ Name >= 92% similar to trusted pkg --> BLOCKED <-- postmark-mcp-evil | Gate 0: Name | Name >= 80% similar --> WARN (manual review) | Similarity Check | Exact allowlist match --> pass immediately | (local, no network) | 3 algorithms: Levenshtein, prefix, char-swap +----------+-----------+ | v +----------------------+ < 24 h, no CVE --> BLOCKED | Gate 1: Age Hold | | 24 h hard block | Zero-day CVE filed? --> Expedited Lane ----------+ | 72 h soft hold | | +----------+-----------+ | | >= 24 h | v | +----------------------+ Repo mismatch --> BLOCKED <-- Miasma/IronWorm | | Gate 2: Provenance | No attestation --> QUARANTINE | | Attestation + | (sourceRepositoryURI vs trusted_publishers.yaml) | | Publisher Allowlist | | +----------+-----------+ | | | v | +----------------------+ Orphan commit --> BLOCKED <-- Miasma/IronWorm | | Gate 2.5: CI/CD | id-token:write --> QUARANTINE | | Pipeline Audit | No PR review --> BLOCKED | +----------+-----------+ <-- Rejoins here --------+ | v +----------------------+ Score < threshold --> QUARANTINE | Gate 3: Out-of-Band | Active CVE --> QUARANTINE | Trust Aggregation | (OpenSSF, OSV, deps.dev, GHSA) +----------+-----------+ | v +----------------------+ New transitive dep --> QUARANTINE | Gate 4: SBOM Delta | Hash mismatch --> QUARANTINE +----------+-----------+ | v +----------------------+ Tor C2 --> BLOCKED <-- IronWorm: exfil | Gate 5: Behavioral | eBPF rootkit --> BLOCKED <-- IronWorm: rootkit | Sandbox | AI API key harvest --> BLOCKED | 34 patterns active | Cloud cred harvest --> BLOCKED +----------+-----------+ | v +--------------+ | Staged Rollout| --> APPROVED | 72 h canary | +--------------+ ``` ## 关卡参考 | 关卡 | 控制内容 | 失败动作 | 可绕过? | |---|---|---|---| | **0 — 名称相似度** | 包名对比可信白名单 — Levenshtein、前缀添加、字符交换检测 | 警告 (>=80%) · 阻断 (>=92%) | 否 | | **1 — 年限(Age)** | 发布时间戳对比 24 小时 / 72 小时阈值 | 阻断 / 暂扣 | 仅年限关卡 — 需 CVE + MFA 法定人数 | | **2 — 来源出处(Provenance)** | 存在 Sigstore 证明;`sourceRepositoryURI` 匹配白名单 | 阻断(不匹配) · 隔离(缺失) | 否 | | **2.5a — 孤立提交** | 通过 BFS 图遍历,发布标签提交可从默认分支到达 | 阻断 | 否 | | **2.5b — 工作流权限** | 在发布工作流中具有 `id-token: write` 且无补偿性控制 | 隔离 | 否 | | **2.5c — PR 来源** | 版本发布由 >= 1 名审查者批准合并的 PR 支撑 | 阻断(无 PR) · 隔离(无审查) | 否 | | **3 — OOB 信任** | OpenSSF Scorecard >= 阈值;通过 OSV + deps.dev + GHSA 发现零活跃 CVE | 隔离 | 否 | | **4 — SBOM 增量** | 无意外的传递依赖;lock 文件哈希未更改 | 隔离 | 否 | | **5 — 行为沙箱** | gVisor/strace 安装时执行;34 种命名的行为模式(18 种 Miasma + 16 种 IronWorm) | 阻断 | 否 | ## 攻击覆盖范围 ### Mma / Shai-Hulud — Red Hat Insights (2026) | 攻击步骤 | 关卡 | 机制 | |---|---|---| | 推送孤立提交,绕过 PR | **2.5a** | BFS 遍历;标签提交无法从 main 到达 -> BLOCK | | 恶意提交未进行代码审查 | **2.5c** | 无已合并的 PR -> DIRECT_PUSH -> BLOCK | | `id-token: write` 被利用于 OIDC 发布 | **2.5b** | 危险权限 + 无环境保护 -> QUARANTINE | | 从员工分支发布,而非标准组织 | **2** | `sourceRepositoryURI` 不匹配 -> BLOCK | | 云凭证收集 (GCP/Azure IMDS) | **5** | MIASMA-001/002: IMDS 网络事件 -> BLOCK | | 从安装上下文请求 OIDC token | **5** | MIASMA-010: `token.actions.githubusercontent.com` -> BLOCK | | 从安装脚本重新发布到 npm | **5** | PUBLISH-001: PUT 请求到 `registry.npmjs.org` -> BLOCK | ### IronWorm — asteroiddao / Arweave 生态系统 (JFrog, 2026-06-03) | 攻击步骤 | 关卡 | 机制 | |---|---|---| | 从被入侵的 `asteroiddao` 账户发布 | **2** | `sourceRepositoryURI` 不匹配 -> BLOCK | | 具有倒签时间戳的孤立提交 | **2.5a** | 图可达性 — 时间戳无关 -> BLOCK | | 通过 `preinstall` hook 投递 Rust ELF 二进制文件 | **5** | IRONWORM-002b: `tools/setup` 进程事件 -> BLOCK | | eBPF 内核 rootkit 加载 | **5** | IRONWORM-002: `BPF_PROG_LOAD` 系统调用 -> BLOCK | | AI API 密钥收集 (OpenAI、Anthropic、Gemini) | **5** | IRONWORM-003: `OPENAI_API_KEY`、`ANTHROPIC_API_KEY` -> BLOCK | | AWS / GCP / Azure / Vault 凭证窃取 | **5** | CRED-003/004 + IRONWORM-004 -> BLOCK | | Tor 隐藏服务 C2 信标 | **5** | IRONWORM-001: `.onion` 网络事件 -> BLOCK | | 窃取 npm token 用于自我传播 | **5** | IRONWORM-006/006b: 读取 `.npmrc` + `NPM_AUTH_TOKEN` -> BLOCK | ## 零日通道断路器 | 条件 | 动作 | |---|---| | 24小时内超过 3 次例外请求 | 暂停通道,等待 CISO 审查 | | 同一请求者在 48 小时内提出两次例外 | 第二次请求升级为 CISO 签字批准 | | 任何通过例外部署的包在 30 天内收到新的 CVE | 暂停通道;触发回顾性审查 | 例外 Token 在 6 小时后过期。需要重新批准 — 不予延期。 ## 运行测试 ``` # 完整套件 — 131 项测试,全部离线 (无需网络) pytest # 按 gate pytest tests/test_gate1_age.py # 11 tests — age threshold boundaries pytest tests/test_gate3_trust.py # 6 tests — OOB trust aggregation pytest tests/test_gate5_behavioral.py # 50 tests — all 34 named patterns pytest tests/test_zeroday_lane.py # 23 tests — full quorum lifecycle pytest tests/test_integration.py # 10 tests — cross-gate scenarios # 带覆盖 pytest --cov=oss_trust_framework --cov-report=term-missing ``` 所有外部 API 调用(PyPI、OSV、OpenSSF、GitHub)均已被模拟(mocked)— 测试完全在离线状态下运行。 ## OWASP Top 10 CI/CD 安全风险覆盖 | 风险 | 框架覆盖范围 | 关卡 | |---|---|---| | **CICD-SEC-1** 流控制不足 | 年限关卡强制执行暂扣。零日通道需要 CVE + 2/3 的 MFA 法定人数。任何个人都无法单方面加速。 | 关卡 1, ZD 通道 | | **CICD-SEC-2** IAM 不当 | 关卡 2.5b 审计 `id-token: write`。关卡 2.5c 强制执行审查人数。ZD 法定人数强制执行职责分离。 | 关卡 2.5b, 2.5c, ZD 通道 | | **CICD-SEC-3** 依赖链滥用 | 核心任务。关卡 1-5 验证每一个依赖更新。 | 关卡 1-5 | | **CICD-SEC-4** 中毒的流水线执行 | 关卡 2.5a 检测孤立提交。关卡 2.5c 确认 PR 审查。关卡 2.5b 标记危险权限。 | 关卡 2.5a, 2.5b, 2.5c | | **CICD-SEC-5** PBAC 不足 | 关卡 2.5b 对发布工作流强制执行基于流水线的访问控制。 | 关卡 2.5b | | **CICD-SEC-6** 凭证卫生不足 | 关卡 5 在安装时检测凭证收集(AWS/GCP/Azure、Vault、npm、AI API 密钥)。 | 关卡 2, 5 | | **CICD-SEC-7** 不安全的系统配置 | 关卡 2.5b 检查是否缺失分支保护、CODEOWNERS、环境保护规则。 | 关卡 2.5b | | **CICD-SEC-8** 不受管控的第三方服务 | 关卡 3 独立查询 OpenSSF、OSV、deps.dev、GHSA。关卡 4 SBOM 增量捕获意外的传递依赖。 | 关卡 3, 4 | | **CICD-SEC-9** 制品完整性不当 | 关卡 2 验证 Sigstore/GPG 签名和 `sourceRepositoryURI`。关卡 4 锁定哈希。关卡 2.5a 验证标签可达性。 | 关卡 2, 2.5a, 4 | | **CICD-SEC-10** 日志记录不足 | 每个关卡决策都会发出结构化的 SIEM 事件。零日例外需要关联工单。完整的不可否认审计跟踪。 | 所有关卡, ZD 通道 | ## 项目结构 ``` oss-trust-framework/ +-- oss_trust_framework/ # Installable Python package (pip install oss-trust-framework) | +-- check_all.py # oss-trust check-all command | +-- name_similarity/checker.py # Gate 0 -- typosquat detection | +-- age_check/checker.py # Gate 1 -- multi-ecosystem age check | +-- signature/provenance.py # Gate 2 -- Sigstore attestation + allowlist | +-- cicd_audit/ # Gate 2.5 -- CI/CD pipeline audit | +-- trust/aggregator.py # Gate 3 -- OpenSSF/OSV/deps.dev/GHSA | +-- sbom/differ.py # Gate 4 -- SBOM delta + hash pin | +-- sandbox/ # Gate 5 -- behavioral sandbox (34 patterns) | +-- zeroday/validator.py # CVE validation + quorum approval | +-- pipeline/orchestrator.py # Full pipeline runner | +-- cli.py # oss-trust CLI entry point +-- scripts/check_all.py # Multi-ecosystem batch checker (all 7 registries) +-- check_all.py # Repo-root shim (python check_all.py) +-- config/ | +-- pipeline.yaml # Gate thresholds and circuit breakers | +-- trusted_publishers.yaml # Publisher allowlist (100+ packages, 7 ecosystems) +-- requirements.txt # Framework runtime deps (pinned, Dependabot-clean) +-- framework_deps.txt # Self-validation dep declarations +-- tests/ # 131 tests, all offline +-- docs/index.html # Full documentation site +-- .github/workflows/ +-- dep-trust-check.yml # PR gate: auto-runs on lock file changes +-- publish.yml # PyPI publish on GitHub Release ``` ## 供应链完整性对比运行时监控 该框架在依赖项**进入您的环境之前**对其进行验证。它不是一个运行时安全监控器。 | 威胁 | 是否覆盖? | 如未覆盖,请使用 | |---|---|---| | 恶意安装脚本 (IronWorm preinstall hook) | 关卡 5 | — | | 被入侵的发布者账户 | 关卡 2, 2.5, 5 | — | | Typosquat(域名拼写错误)/ 冒充 | 关卡 0 | — | | 依赖项中已知的 CVE | 关卡 3 | — | | 运行时数据渗出 (MCP server 密送电子邮件) | 否 | Falco, Tetragon | | 延迟激活(满足条件后发送信标) | 否 | 运行时监控 | | 语义冒充(字符串相似度低) | 否 | 人工白名单审查 | ## 许可证 MIT — 参见 [LICENSE](LICENSE)。 ## 参考 - [IronWorm: Shai-Hulud 的 Rust 近亲 — JFrog 安全研究](https://research.jfrog.com/post/iron-worm-shai-hulud-rustier-cousin/) - [IronWorm 恶意软件攻击 36 个 npm 包 — BleepingComputer](https://www.bleepingcomputer.com/news/security/new-ironworm-malware-hits-36-packages-in-npm-supply-chain-attack/) - [Miasma 入侵 32 个 Red Hat npm 包 — devops.com](https://devops.com/shai-hulud-clone-miasma-compromises-32-red-hat-npm-packages/) - [TanStack npm 供应链攻击 — Security Boulevard](https://securityboulevard.com/2026/05/the-tanstack-npm-supply-chain-attack-that-hit-170-packages-and-punishes-you-for-revoking-your-token/) - [Bitwarden CLI 入侵 — Security Boulevard](https://securityboulevard.com/2026/04/bitwarden-cli-compromise-linked-to-ongoing-checkmarx-supply-chain-campaign/) - [OpenSSF Scorecard](https://securityscorecards.dev) - [Sigstore / cosign](https://docs.sigstore.dev) - [OSV — 开源漏洞](https://osv.dev) - [Google deps.dev](https://deps.dev) - [SLSA 框架](https://slsa.dev) - [npm 来源出处证明](https://docs.npmjs.com/generating-provenance-statements) - [PyPI 可信发布者](https://docs.pypi.org/trusted-publishers/) - [gVisor 容器沙箱](https://gvisor.dev)
标签:LNA, 逆向工具