prakhar0x01/sentryd

GitHub: prakhar0x01/sentryd

Sentryd 是一款 AI 辅助的软件供应链安全扫描器,专注于发现恶意包和 pipeline 攻击而非仅检测已知 CVE,并能自动生成蓝队检测规则。

Stars: 0 | Forks: 0

# 🛡️ Sentryd **AI 辅助的软件供应链防御。** Sentryd 旨在发现*恶意*包和 pipeline 漏洞 —— 而不仅仅是已知的 CVE —— 它用通俗易懂的英文解释每一项发现,并将检测规则交给您的蓝队, 以便在生产环境中捕获相同的攻击。 [功能](#features) · [架构](#architecture-overview) · [安装](#installation) · [快速开始](#quick-start) · [用法](#usage-guide) · [配置](#configuration) · [示例](#examples) · [工作原理](#how-it-works) · [常见问题](#faq) · [贡献](#contributing)
## 目录 - [什么是 Sentryd?](#what-is-sentryd) - [诞生背景](#why-it-exists) - [功能](#features) - [架构概览](#architecture-overview) - [安装说明](#installation) - [快速开始](#quick-start) - [使用指南](#usage-guide) - [配置](#configuration) - [示例](#examples) - [工作原理](#how-it-works) - [故障排除](#troubleshooting) - [常见问题](#faq) - [开发](#development) - [项目结构](#project-structure) - [安全考量](#security-considerations) - [贡献](#contributing) - [路线图](#roadmap) - [许可证](#license) - [鸣谢](#credits) ## 什么是 Sentryd? Sentryd 是一个命令行**软件供应链扫描器**。您只需将它指向一个 代码仓库(或单个已发布的包),它就能回答大多数扫描器 无法回答的问题: 它分两个层级执行此操作: 1. 一个**低成本、确定性的静态层**,该层始终运行并查找可疑项 (域名抢注、安装钩子、依赖混淆、未锁定的依赖、 中毒的 CI workflow、已知漏洞)。 2. 一个**可选的 LLM 层**(`--deep`),它会获取被标记的包,安全地 解压它,仅将可疑片段发送给模型,并返回 可解释的行为判定。 然后,它将发现结果转化为安全团队实际使用的产出物:用于 GitHub 代码扫描的 **SARIF**、**SBOMs**(CycloneDX / SPDX),以及可直接部署的 **Sigma / KQL / Falco / YARA** 检测规则。 ## 诞生背景 供应链安全中拥挤的领域是**已知漏洞** —— “您 依赖于存在 CVE-Y 的 lodash X。” 这是一个已经解决的大众化问题。 而尚未解决且极具价值的领域是**蓄意设计的恶意代码**,当它刚落地时 没有任何特征码: - 一个包,在执行 `postinstall` 时,会窃取您的 npm/PyPI token 并将其 自身重新发布到您拥有的每一个包中(即 **Shai-Hulud** 蠕虫类别)。 - **依赖混淆** —— 一个公共包抢占了内部名称,而您的构建过程 会默默地优先选择它。 - **域名抢注 (Typosquats)** —— 携带 payload 的 `loadsh`、`reqeusts`、`python-dateutil` 克隆体。 - GitHub Actions 中的**中毒 pipeline 执行** —— 未锁定的 action 或 过度授权的 `GITHUB_TOKEN`,它将一个 pull request 变成了 在您的 CI runner 上执行的代码。 基于特征码的工具会漏掉这些,因为目前还没有特征码。要捕获它们 需要对**行为**进行推理 —— 这正是被强大的静态预过滤器限制住的 LLM 发挥作用的地方,同时扫描一个干净的代码仓库的成本依然约为 $0。 两项原则让 Sentryd 值得信赖: - **从不执行不受信任的代码。** 分析是完全静态的 —— 获取、安全 解压、读取、推理。指向真正恶意的包也是安全的。 - **AI 是被限制的,而不是随意洒落的。** 静态层决定模型能看到什么, 从而控制成本,并且模型经过强化,能够抵御来自恶意 包源码的 prompt injection。 ## 功能 | 领域 | 您将获得什么 | |---|---| | **生态系统** | npm(精确到 lockfile,包含传递依赖)、PyPI(`requirements.txt`)、Cargo(`Cargo.lock`)。支持插件化 —— 添加一个新生态仅需一个模块。 | | **静态检测器** | 域名抢注、npm 安装钩子、未锁定的依赖、GitHub Actions 安全态势(未锁定的 actions、`write-all` token)。每一个都附带了真阳性**和**真阴性测试用例。 | | **数据增强** | OSV.dev 已知漏洞查询、deps.dev 传递依赖解析、基于注册表的依赖混淆检测。带有缓存;在离线状态下可优雅降级。 | | **LLM 行为层** | `--deep` 获取并安全解压包,对可疑文件进行分流,并通过 Anthropic API 返回结构化的 `{verdict, confidence, behaviors[], explanation, remediation}`。能够抵御 prompt injection。 | | **可解释的发现** | 没有光秃秃的评分 —— 每一个发现都包含证据、解释和修复建议。 | | **检测规则生成** | 经过验证的 **Sigma**(通过 pySigma)、**KQL**、**Falco** 和 **YARA**,根据发现的行为生成,带有 MITRE ATT&CK 标签和客观的误报提示。 | | **策略即代码** | 在 `sentryd.policy.yaml` 中定义 `allow` / `deny` / `warn` 规则,在 CI 检查关口强制执行。 | | **输出** | 丰富的终端表格、JSON、适配 GitHub 的 **SARIF**、独立的 **HTML 报告**,以及 **CycloneDX / SPDX SBOMs**。 | | **易用性** | 已发布的 **GitHub Action**、**pre-commit hook**、`--fail-on` CI 检查关口,以及 `--notify`(Slack / webhook)。 | | **红队测试面** | 被禁用的恶意包语料库、查准率/查全率**基准测试**,以及**规避测试套件** —— `sentryd redteam`。 | | **注册表监控** | `sentryd watch` 扫描发布到 PyPI 的最新包,以发现可疑行为。 | | **工程质量** | 严格类型检查(`mypy --strict`)、`ruff` lint + format、`pytest` 测试套件(单元 / 集成 / 语料库 / 可选的实时测试),以及自扫描(“吃自己的狗粮”)CI pipeline。 | ## 架构概览 Sentryd 是一个分层的 pipeline。每一层仅依赖于它下方的层; `core` 包是所有人都会导入的共享底层基础。 ``` ┌──────────────────────────────────────────────┐ │ CLI │ │ scan · scan-package · ci · sbom · rules · │ │ watch · redteam │ └───────────────────────┬────────────────────────┘ │ ┌───────────┐ ┌───────────┐ ┌──────▼──────────────┐ ┌──────────────┐ │ INGEST │───▶│ ENRICH │───▶│ ANALYSIS │───▶│ OUTPUT │ │ npm/pypi/ │ │ OSV │ │ static tier (always)│ │ table · json │ │ cargo │ │ deps.dev │ │ LLM tier (--deep) │ │ SARIF · HTML │ │ + fetch │ │ registry │ │ correlate + policy │ │ SBOM · rules │ └───────────┘ └───────────┘ └─────────────────────┘ └──────────────┘ │ cross-cutting: SANDBOX (no-exec extract) · CACHE · CONFIG · LOGGING · PLUGIN REGISTRY ``` ### 数据流 1. **摄取** 将项目目录转化为 `DependencyGraph`(如果存在 lockfile,则从中解析出版本)。纯静态读取 —— 绝不执行安装钩子。 2. **增强**(网络相关,可选)添加 OSV 已知漏洞发现结果,当没有 lockfile 时通过 deps.dev 扩展传递图,并通过注册表中名称的存在性来检查依赖混淆。 3. **静态分析** 针对该图运行声明式检测器(数据位于 `detectors/*.yaml` 中)。确定性执行且始终开启。 4. **LLM 分析**(`--deep`)仅针对被标记的包运行,且仅针对相关的切片:获取 -> 安全解压 -> 选择可疑文件 -> 模型 -> 结构化判定。 5. **关联** 合并静态和 LLM 信号,进行去重、评分,并应用 **策略**(allow/deny/warn)。 6. **输出** 呈现结果(表格 / JSON / SARIF / HTML / SBOM),并且可以 根据行为生成检测规则。 ### 设计决策 - **检测器是数据,而不是代码。** 一项新检查就是一个 YAML 定义加上一个 可复用的评估器 —— 保持贡献摩擦力低且引擎整洁。 - **两层分流控制成本。** 昂贵的模型只能看到免费层 标记的内容,并且仅仅是其相关的切片。 - **所有结构化的内容都是 Pydantic 模型**(`core/models.py`)—— 子系统之间的 契约。人类可读的输出使用 Rich;机器输出在 stdout 上是纯净的字节流,因此可以通过管道完美传输。 ## 安装说明 ### 前置条件 | 需求 | 说明 | |---|---| | **Python 3.12+** | CI 环境已测试 3.12 和 3.13 版本。 | | **[uv](https://docs.astral.sh/uv/)** | 推荐的安装器/运行器。它会自动配置合适的 Python。 | | 网络(可选) | 增强功能(`OSV`、`deps.dev`)、`--deep`、`scan-package` 和 `watch` 所需。其他所有功能均可离线工作。 | | `ANTHROPIC_API_KEY`(可选) | 仅在 `--deep` LLM 层必需。如果没有它,Sentryd 将以纯静态模式运行。 | ### 支持的操作系统 支持 Linux、macOS 和 Windows(纯 Python 实现,无原生构建步骤)。 ### 安装 `uv` **macOS / Linux:** ``` curl -LsSf https://astral.sh/uv/install.sh | sh ``` (macOS 用户也可以执行 `brew install uv`。) **Windows (PowerShell):** ``` powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` ### 从源码安装 Sentryd ``` git clone https://github.com/prakhar0x01/sentryd cd sentryd uv sync # creates .venv and installs everything uv run sentryd --help # verify ``` `uv run sentryd ...` 会在受管环境中运行 CLI。要在您的 `PATH` 中获得直接的 `sentryd` 命令,请将该项目作为工具安装: ``` uv tool install . sentryd --help ``` ## 快速开始 ``` # 1. 扫描仓库(静态,支持离线) uv run sentryd scan ./your-repo # 2. 添加深度行为分析(需要 API key) export ANTHROPIC_API_KEY=sk-ant-... uv run sentryd scan ./your-repo --deep # 3. 分析单个已发布的 package uv run sentryd scan-package express@4.18.2 # 4. 用作 CI 门禁(发现 high+ 级别的问题以非零状态退出,并输出 SARIF) uv run sentryd ci ./your-repo --fail-on high > results.sarif # 5. 从上次扫描中生成蓝队检测规则 uv run sentryd rules --from last-scan --format all --output ./rules ``` ## 使用指南 ### 命令 | 命令 | 用途 | |---|---| | `sentryd scan ` | 扫描项目:依赖项、lockfile 和 CI 配置。 | | `sentryd scan-package ` | 获取并分析单个已发布的包,例如 `express@4.18.2`。 | | `sentryd ci ` | CI 检查关口模式:生成机器可读的产出物(默认为 SARIF),并在发生策略/严重性违规时以非零状态退出。 | | `sentryd sbom ` | 生成 CycloneDX 或 SPDX 的软件物料清单 (SBOM)。 | | `sentryd rules --from last-scan` | 根据上次扫描的发现结果输出经过验证的 Sigma/KQL/Falco/YARA 规则。 | | `sentryd watch [pypi]` | 扫描发布到注册表的最新包,以发现可疑行为。 | | `sentryd redteam --suite all` | 运行语料库基准测试和规避测试套件。 | | `sentryd --version` | 打印版本信息。 | 运行任何带有 `--help` 的命令以查看其完整选项。 ### 典型工作流:扫描代码仓库 ``` # 静态扫描(快速,除了 OSV enrichment 外无需网络) uv run sentryd scan ./my-app # 完全离线(跳过 OSV / deps.dev / registry 查找) uv run sentryd scan ./my-app --no-enrich # 对标记的 packages 进行深度行为分析 uv run sentryd scan ./my-app --deep --fail-on high # 用于工具的机器输出 uv run sentryd scan ./my-app --output json > scan.json uv run sentryd scan ./my-app --output sarif > scan.sarif uv run sentryd scan ./my-app --output html > report.html ``` ### 进阶用法 ``` # 执行组织策略(allow/deny/warn) uv run sentryd scan ./my-app --policy sentryd.policy.yaml # 通过 scan summary 通知 Slack / 通用 webhook uv run sentryd scan ./my-app --notify "$SLACK_WEBHOOK_URL" # 仅生成 Sigma 规则到目录中 uv run sentryd rules --format sigma --output ./detections # 使用 LLM tier 监控 50 个最新的 PyPI packages uv run sentryd watch pypi --limit 50 --deep ``` ### 在 CI 中 (GitHub Action) 发现结果会通过 SARIF 在 GitHub 的 **Security** 标签页中原生呈现: ``` # .github/workflows/supplychain.yml name: supply-chain on: [push, pull_request] permissions: contents: read security-events: write # required to upload SARIF to code scanning jobs: sentryd: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: prakhar0x01/sentryd@v1 with: path: . fail-on: high ``` ### 作为 pre-commit hook ``` # .pre-commit-config.yaml repos: - repo: https://github.com/prakhar0x01/sentryd rev: v0.1.0 hooks: - id: sentryd ``` ## 配置 配置将从以下来源解析,**后者会覆盖前者**: 1. 内置默认值。 2. 被扫描目录中的 `sentryd.yaml`。 3. `~/.config/sentryd/config.yaml`(用户级别)。 4. 通过 `--config` 传递的文件。 5. 环境变量。 6. CLI 标志。 ### 配置文件 (`sentryd.yaml`) 复制 [`sentryd.yaml.example`](./sentryd.yaml.example): ``` api_key: "" # prefer the ANTHROPIC_API_KEY env var fail_on: high # info | low | medium | high | critical deep: false # enable the LLM tier (auto-disabled without a key) enrich: true # OSV / deps.dev / registry lookups (false = offline) ecosystems: [npm, pypi] output: json # json | sarif | html cache_dir: ~/.cache/sentryd log_level: warning # debug | info | warning | error # policy_file: sentryd.policy.yaml ``` ### 环境变量 | 变量 | 用途 | |---|---| | `ANTHROPIC_API_KEY` | 用于 `--deep` LLM 层的 API key。 | | `SENTRYD_FAIL_ON` | 触发失败的最低严重性。 | | `SENTRYD_DEEP` | `true`/`false` —— 启用 LLM 层。 | | `SENTRYD_ENRICH` | `true`/`false` —— 启用网络数据增强。 | | `SENTRYD_OUTPUT` | 默认输出格式。 | | `SENTRYD_ECOSYSTEMS` | 逗号分隔的生态系统,例如 `npm,pypi`。 | | `SENTRYD_CACHE_DIR` | 缓存目录。 | | `SENTRYD_LOG_LEVEL` | 日志记录级别。 | | `LOG_FORMAT` | 设置为 `json` 以在 CI 中输出结构化日志。 | 关键标志 | 标志 | 命令 | 默认值 | 含义 | |---|---|---|---| | `--deep` | `scan`, `scan-package`, `watch` | 关闭 | 启用 LLM 行为层。 | | `--fail-on` | `scan`, `ci` | `high` | 决定以非零状态退出的最低严重性。 | | `--output` | `scan`, `scan-package`, `ci` | table / sarif | `json` \| `sarif` \| `html`。 | | `--no-enrich` | `scan` | 关闭 | 跳过网络增强(完全离线)。 | | `--policy` | `scan`, `ci` | 无 | 指向 `sentryd.policy.yaml` 的路径。 | | `--notify` | `scan`, `ci` | 无 | 用于 POST 扫描摘要的 Webhook/Slack URL。 | | `--format` | `sbom`, `rules` | — | SBOM / 规则格式选择器。 | ### 策略即代码 (`sentryd.policy.yaml`) ``` version: "1" rules: - action: deny # fail the build on this finding, any severity rule_id: typosquat-popular reason: "No typosquats permitted in production builds" - action: warn # report but never fail severity_min: medium reason: "Surface medium+ findings for review" - action: allow # suppress an approved exception package_name: internal-auth-sdk reason: "Approved internal package" ``` 规则从上到下求值;匹配的第一条规则生效。 ## 示例 ### 1. 域名抢注检测 **输入** —— 一个依赖于 `loadsh`(`lodash` 的域名抢注)的 `package.json`。 **命令:** ``` uv run sentryd scan ./my-app ``` **输出:** ``` ╭──────────────── Sentryd ─────────────────╮ │ Scanning ./my-app... │ ╰──────────────────────────────────────────╯ Findings ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Severity ┃ Conf. ┃ Rule ┃ Package ┃ Explanation ┃ ┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━┩ │ high │ medium │ typosquat-popular │ loadsh@1.0.0 │ Dependency 'loadsh' │ │ │ │ │ │ is within edit │ │ │ │ │ │ distance 1 of the │ │ │ │ │ │ popular package │ │ │ │ │ │ 'lodash'. │ └──────────┴────────┴───────────────────┴──────────────┴───────────────────────┘ 1 findings in 1 package(s) · static only · 0.003s ``` ### 2. 用于工具对接的 JSON 输出 **命令:** ``` uv run sentryd scan ./my-app --output json ``` **输出(经裁剪):** ``` { "scanned_path": "./my-app", "packages_scanned": 1, "llm_tier_used": false, "findings": [ { "rule_id": "npm-install-hook", "severity": "medium", "package": "my-app@0.0.1" }, { "rule_id": "unpinned-dependency", "severity": "low", "package": "left-pad@^1.3.0" } ] } ``` ### 3. 生成检测规则 **命令:** ``` uv run sentryd scan ./my-app # produces the last scan uv run sentryd rules --from last-scan --format sigma ``` **输出(一条生成的、通过 pySigma 验证的规则):** ``` title: Package manager install hook spawns a child process id: 3c2303a6-460d-49bb-8b02-5f2f5b2d5762 status: experimental logsource: category: process_creation product: linux detection: selection: ParentImage|endswith: ['/npm', '/yarn', '/pnpm', '/pip', '/node'] CommandLine|contains: ['postinstall', 'preinstall', 'sh -c', 'curl', 'wget'] condition: selection level: medium tags: - attack.t1195.002 falsepositives: - Native modules with legitimate build steps (node-gyp, prebuild) ``` ### 4. 红队基准测试 + 规避套件 **命令:** ``` uv run sentryd redteam --suite all ``` **输出:** ``` Corpus benchmark (static tier) ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Entry ┃ Expected ┃ Detected ┃ Outcome ┃ Detectors ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩ │ ci-poisoned-pipeline │ malicious │ yes │ TP │ gha-broad-permissio… │ │ npm-clean-lib │ benign │ no │ TN │ - │ │ npm-install-stealer │ malicious │ yes │ TP │ npm-install-hook │ │ npm-scoped-private │ benign │ no │ TN │ - │ │ npm-typosquat-loadsh │ malicious │ yes │ TP │ typosquat-popular │ └──────────────────────┴───────────┴──────────┴─────────┴──────────────────────┘ precision=1.00 recall=1.00 f1=1.00 (tp=3 fp=0 fn=0 tn=2) Evasion suite (vs static tier) ... baseline / preinstall-hook / prepare-hook / external-file / obfuscated-command → caught ; runtime-only → BYPASS 1/6 variant(s) bypassed the static tier — each is a documented gap handled by the LLM tier. ``` ### 5. 包的深度行为分析 **命令:** ``` export ANTHROPIC_API_KEY=sk-ant-... uv run sentryd scan-package some-suspicious-pkg@1.0.0 --deep --output json ``` **输出(结构):** ``` { "findings": [{ "rule_id": "llm-behavioral", "name": "LLM behavioral verdict: malicious", "severity": "critical", "llm_verdict": { "verdict": "malicious", "confidence": 0.95, "self_propagation": false, "behaviors": [{ "behavior": "credential-exfiltration", "evidence": "postinstall reads ~/.npmrc and POSTs it to http:///c", "location": "scripts/postinstall.js:12-19" }], "explanation": "The install hook reads the npm auth token and sends it to a remote host.", "remediation": "Do not install this package; rotate any exposed npm tokens." } }] } ``` ## 工作原理 首次扫描的引导式演练。 1. **您运行扫描。** uv run sentryd scan ./my-app --fail-on high 2. **Sentryd 检测生态系统并构建依赖图。** 它会找到 `package.json`(如果存在还有 lockfile)并解析出确切、完整的传递 包集合 —— 仅读取字节,绝不执行任何内容。 3. **运行增强(如果在线)。** 每个确切版本的包都会与 OSV.dev 进行比对,以检查已知漏洞;直接依赖项会被检查是否存在 依赖混淆(即在公共注册表中无法声明的名称)。在此期间,您会看到 `Scanning ./my-app...` 面板。 4. **静态层评估每个检测器。** 域名抢注、安装钩子、 未锁定的依赖项以及 CI 安全态势问题会作为发现结果呈现 —— 每一项 都附带证据和修复建议。 5. **(可选)深度层分析被标记的包。** 结合 `--deep` 和 API key,Sentryd 会获取每个被标记的包,安全地将其解压,仅选择 可疑文件,并向模型请求结构化的行为判定。 6. **您将看到结果**,以按严重性着色的表格形式呈现(最严重的在最上面),以及一行摘要, 例如 `2 findings in 37 package(s) · static only · 0.4s`。 7. **检查关口决定退出代码。** 如果任何发现结果达到或超过 `--fail-on` (或匹配了策略 `deny`),Sentryd 将以非零状态退出 —— 从而使您的 CI 失败。 8. **接下来您可以。** 为 SOC 生成检测规则 (`sentryd rules --from last-scan`),在 GitHub 的 Security 标签页中打开 SARIF,或者 为已审查确认的误报添加 `allow` 策略规则。 ## 故障排除 | 症状 | 原因 | 解决方法 | |---|---|---| | `LLM tier: no API key set, skipping.` | 在没有 `ANTHROPIC_API_KEY` 的情况下使用了 `--deep`。 | `export ANTHROPIC_API_KEY=sk-ant-...`,或者去掉 `--deep`。 | | 扫描卡住或运行缓慢 | 在大型依赖图或慢速网络连接上进行网络增强(OSV/deps.dev)。 | 添加 `--no-enrich` 进行快速的离线扫描。 | | `Invalid value for 'PATH': ... does not exist` | 扫描路径错误。 | 传入一个存在的路径;对于单个包,请使用 `scan-package`。 | | `sentryd rules` 提示 “No previous scan found” | 尚未运行过任何扫描(规则读取的是上一次扫描结果)。 | 先运行 `sentryd scan `。 | | `watch npm ...` 被拒绝 | 目前只有 PyPI 支持最新包的数据流。 | 请使用 `sentryd watch pypi`。 | | 在您自己代码仓库的 CI 上发现结果 | Sentryd 标记了未锁定的 GitHub Actions / `write-all` token。 | 将 actions 锁定到 commit SHA 并限制 `permissions:` 范围,或者添加 `allow`/`warn` 策略规则。 | | Security 标签页中没有 SARIF | 缺少 `security-events: write` 权限。 | 将其添加到 workflow 的 `permissions:` 块中。 | 要进行调试,请提高日志级别: ``` SENTRYD_LOG_LEVEL=debug uv run sentryd scan ./my-app # human logs on stderr LOG_FORMAT=json SENTRYD_LOG_LEVEL=info uv run sentryd scan ./my-app # structured ``` ## 常见问题 **Sentryd 会执行它扫描的包吗?** 不,绝对不会。分析是完全静态的 —— 它获取 tarball,使用 经过强化且禁止执行的解压器解压它们,然后读取字节。安装钩子、`setup.py` 以及 类似的东西永远不会被运行。这也是为什么将其指向恶意包是安全的。 **我需要 API key 吗?** 仅在 `--deep` LLM 层需要。其他所有功能 —— 静态检测器、OSV 增强、SARIF/SBOM、检测规则 —— 没有它也能正常工作。 **深度层的成本是多少?** 一个干净的代码仓库成本约为 $0,因为没有任何内容会发送到模型。只有静态 层标记的包才会被分析,并且仅发送相关的切片区域。判定结果 会被缓存,因此重新扫描相同的版本是免费的。 **支持哪些生态系统?** 目前支持 npm、PyPI 和 Cargo。插件架构使得添加 Go、Maven 或 RubyGems 仅需单个模块。 **它准确吗?** 静态层已针对禁用的恶意包语料库 (`sentryd redteam --suite benchmark`)进行了基准测试,并为 每个检测器提供了真阳性和真阴性测试用例。我们将误报视为比 漏报更严重的问题。 **我可以完全离线运行它吗?** 可以:`sentryd scan --no-enrich` 会跳过所有的网络调用。 **为什么我自己的代码仓库会被标记?** 如果您的 CI workflow 使用了未锁定的 actions 或 `write-all` token,Sentryd 就会 报告它 —— 这是一个真实的安全态势发现。请将其锁定到 SHA、限制权限范围,或者通过策略允许它。 ## 开发 ``` git clone https://github.com/prakhar0x01/sentryd cd sentryd uv sync ``` ### 质量检查关口(每次提交前运行) ``` uv run ruff check . # lint uv run ruff format --check . # formatting uv run mypy src/ # strict type checking uv run pytest -q # full test suite ``` 或者一次性全部运行: ``` uv run ruff check . && uv run ruff format . && uv run mypy src/ && uv run pytest -q ``` ### 测试套件 ``` uv run pytest -q # everything (live tests auto-skip) uv run pytest -m corpus # malicious-package zoo regression RUN_LIVE=1 uv run pytest -m live # opt-in tests that hit the real Anthropic API (cost money) ``` 该套件包含 32 个测试模块,覆盖了单元测试、集成测试、端到端测试(通过 Typer 的 `CliRunner`)以及语料库回归测试。网络代码使用 `pytest-httpx` 进行 mock;LLM 分析器则使用注入的 fake client 进行测试。 ### 调试 - `SENTRYD_LOG_LEVEL=debug` 会在 stderr 上输出 pipeline 日志。 - `LOG_FORMAT=json` 输出供机器消费的结构化日志。 - 机器可读的输出(`--output json|sarif`)在 stdout 上是纯净的字节流;状态/日志会输出到 stderr,因此 `sentryd ci . | jq` 可以正常工作。 请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md) 获取完整的贡献指南,包括 如何添加检测器。 ## 项目结构 ``` sentryd/ ├── src/sentryd/ │ ├── cli.py # Typer entrypoint and command wiring (composition root) │ ├── core/ # models, config, cache, logging, console, plugin registry │ ├── ingest/ # npm / pypi / cargo parsers + tarball fetch │ ├── enrich/ # OSV, deps.dev, registry metadata clients │ ├── analysis/ │ │ ├── static/ # detector engine + evaluators (typosquat, install-hook, …) │ │ ├── llm/ # triage, file selection, prompts, analyzer, deep orchestration │ │ ├── correlate.py # merge + dedupe + score findings │ │ └── policy.py # allow/deny/warn evaluation │ ├── rules/ # Sigma/KQL/Falco/YARA generation + validation │ ├── output/ # sarif, html, sbom, json, notifiers │ ├── monitor/ # registry feed watcher (`watch`) │ ├── redteam/ # corpus loader, benchmark, evasion suite │ └── sandbox/ # hardened, no-execution archive extraction ├── detectors/ # declarative detector definitions (YAML) ├── rule_templates/ # Sigma/KQL/Falco/YARA Jinja templates ├── corpus/ # defanged malicious-package zoo + manifests ├── tests/ # pytest suite + fixtures ├── docs/ # MkDocs documentation site ├── action.yml # published GitHub Action ├── .pre-commit-hooks.yaml # pre-commit hook provider ├── sentryd.yaml.example # sample config └── sentryd.policy.yaml.example ``` ## 安全考量 Sentryd 旨在被指向真正恶意的代码。它的安全 保证、威胁模型和已知限制均记录在 [SECURITY.md](./SECURITY.md) 中。简而言之: - 不受信任的代码**绝不执行**;解压经过强化(防止路径遍历、 符号链接和压缩炸弹攻击)。 - LLM 层将包源码视为恶意输入,并从 结构化字段中读取其判定(抵御 prompt injection)。 - 网络出口流量采用白名单制(注册表 / OSV / deps.dev / Anthropic),外加 明确选择启用的 `--notify` webhook。 - 密钥从环境中读取,绝不记录在日志中。 如需报告漏洞,请参阅 [SECURITY.md](./SECURITY.md#reporting-a-vulnerability)。 ## 贡献 欢迎您的贡献!请阅读 [CONTRIBUTING.md](./CONTRIBUTING.md) 了解 开发环境设置、质量标准、不可妥协的安全规则,以及如何添加 检测器。 简而言之:从 `main` 分支切出,使用 [约定式提交 (Conventional Commits)](https://www.conventionalcommits.org/), 保持所有四个质量检查关口全部通过,并为任何 新增的检测同时添加真阳性和真阴性测试。 ## 路线图 已实现并发布:npm/PyPI/Cargo 摄取、OSV/deps.dev/registry 增强、 静态检测器层、LLM 深度层、检测规则生成、 策略即代码、SARIF/SBOM/HTML 输出、GitHub Action + pre-commit hook、 红队语料库/基准测试/规避套件,以及 PyPI 注册表监控。 计划中: - 更多生态系统(Go modules、Maven、RubyGems),通过现有的插件模式实现。 - npm 注册表监控(复制流水线)。 - 可达性分析 —— 确认危险代码路径是否被实际触发。 - 针对语料库的规则查准率/查全率评分。 - PDF 报告和额外的通知接收器。 ## 许可证 在 [MIT 许可证](./LICENSE) 下发布。 ## 鸣谢 由 **[prakhar0x01](https://github.com/prakhar0x01)** 创建并维护。
标签:DLL 劫持, IP 地址批量处理, LLM防护, 云安全监控, 域名收集, 大语言模型, 恶意包检测, 文档安全, 软件供应链安全, 远程方法调用, 逆向工具, 配置审计, 静态分析