TazarSec/ManticoreScanner
GitHub: TazarSec/ManticoreScanner
基于行为分析后端扫描 npm 依赖中恶意代码的 CLI 工具与 GitHub Action,可在安装前拦截供应链攻击。
Stars: 0 | Forks: 0
# ManticoreScanner
使用 Manticore 行为分析后端扫描 npm 依赖项以查找恶意代码。
## 目录
- [要求](#requirements)
- [GitHub Action](#github-action)
- [快速入门](#quick-start)
- [Scan 操作](#scan-action)
- [Setup 操作](#setup-action)
- [CLI](#cli)
- [安装](#install)
- [`manticore scan`](#manticore-scan)
- [`manticore exec`](#manticore-exec)
- [环境变量](#environment-variables)
- [Docker](#docker)
- [验证镜像签名](#verifying-the-image-signature)
- [验证发布构件](#verifying-release-artifacts)
- [许可证](#license)
## 要求
- 一个 [tazarsec.dev](https://tazarsec.dev) 的 Manticore 账户。默认情况下,GitHub Action 通过短期存活的 GitHub OIDC token 进行身份验证,不需要长期存活的 API key。CLI 支持 OIDC 和 API-key 两种认证方式。
- 在 Linux、macOS 或 Windows(amd64 或 arm64)上运行的 GitHub 托管或自托管 runner。
- 一个包含已提交到仓库的 `package.json` 和/或 `package-lock.json` 的 npm 项目。
## GitHub Action
本仓库发布了两个复合 action:
| Action | 目的 |
|---|---|
| `TazarSec/ManticoreScanner@v1` | 对已提交的 lockfile 进行一次性扫描。报告发现的问题,可选择发布 PR 评论,并能在发现可疑包时使 job 失败。 |
| `TazarSec/ManticoreScanner/setup@v1` | 在 runner 的 PATH 中安装 `manticore` CLI,以便您可以从自己的 pipeline 步骤中调用 `manticore scan` 或 `manticore exec`。 |
**使用完整的 commit SHA 进行固定。** Manticore 使用不可变的发布版本,但 commit hash 固定更加健壮,也是 GitHub 为第三方 action 推荐的格式:
```
- uses: TazarSec/ManticoreScanner@ # v1.2.3
```
为了方便,也支持浮动的 `@v1` 和轻量级的 `@v1.2.3` 标签固定,但在加固您的供应链时,推荐使用 SHA 固定选项。
### 快速入门
将以下内容放入 `.github/workflows/manticore.yml`,以便在每次 push 和 pull request 时进行扫描:
```
on: [push, pull_request]
permissions:
contents: read
id-token: write
jobs:
manticore:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #6.0.2
- uses: TazarSec/ManticoreScanner@v1
```
该 action 会自动检测您的 `package-lock.json`(或 `package.json`),使用新生成的 GitHub OIDC token 进行身份验证,在任何非零可疑分数时使 job 失败,并在 job 日志中打印结果表。请参阅下方的 [scan 操作](#scan-action) 以启用 PR 评论、提高失败阈值、输出 SARIF 等功能。
### Scan 操作
对您的 lockfile 运行 `manticore scan` 并报告结果。当您想要一个交钥匙的“开启 PR,并在 PR 上获取发现”的工作流时,请使用此选项。
```
permissions:
contents: read
id-token: write
pull-requests: write
jobs:
manticore:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #6.0.2
- uses: TazarSec/ManticoreScanner@v1
with:
fail-on: 50
vcs-comment: true
```
#### 输入
| 输入 | 描述 | 默认值 |
|---|---|--|
| `auth-mode` | 认证模式:`github-oidc`(默认)或 `api-key`。`github-oidc` 要求工作流授予 `permissions: id-token: write`。 | `github-oidc` |
| `api-key` | Manticore API key。当 `auth-mode: api-key` 时必填;否则被忽略。 | |
| `api-url` | API 基础 URL。 | `https://tazarsec.dev` |
| `file` | `package.json` / `package-lock.json` 的路径。 | 在 `working-directory` 中自动检测 |
| `format` | 输出格式:`table`、`json`、`sarif`。 | `table` |
| `output` | 将结果写入此路径而不是 stdout。 | stdout |
| `fail-on` | 如果任何可疑分数达到或超过此阈值,则使 job 失败。传递一个更高的数字以仅在出现更强信号时进行拦截。 | `1`(任何非零分数都会失败) |
| `ignore-list` | 列出要跳过的包的文件路径 — 参见 [忽略特定包](#ignore-specific-packages)。 | 无 |
| `http-timeout` | 每次请求的 HTTP 超时(秒)。 | `120` |
| `timeout` | 轮询超时(秒)— 在因错误退出或根据 `on-error` 继续之前,等待后端结果的时间。 | `300` |
| `on-error` | 在后端出错或轮询截止时间已过仍有待处理项时的行为:`fail`(以非零状态退出)或 `continue`(以 0 退出)。 | `fail` |
| `production` | 设置为 `true` 以跳过 devDependencies。 | `false` |
| `vcs-comment` | 设置为 `true` 以发布带有发现问题的 PR 评论。 | `false` |
| `include-transitive` | 设置为 `true` 以提交传递依赖 — 参见 [传递依赖](#transitive-dependencies)。 | `false` |
| `insecure` | 允许明文 `http://` API URL。当为 `false` 时需要 TLS。 | `false` |
| `working-directory` | 运行扫描的目录。 | `.` |
| `version` | 固定特定的发布标签(例如 `v1.2.3`)。 | 调用 action 时使用的引用(例如 `v1`) |
### Setup 操作
在 `PATH` 上安装 CLI 并结束。当您想直接驱动 `manticore` 以在执行时对 `npm install` 进行拦截、对动态解析的 lockfile 运行扫描、为代码扫描输出 SARIF 或将其与其他步骤链接时,请使用此选项。
#### 使用 `manticore exec` 拦截安装
`manticore exec` 封装了包管理器的安装命令。它首先**不执行安装脚本**,将依赖树解析为 lockfile,扫描每个包,并且只有在扫描通过时才调用真正的安装。这会在运行器上的恶意 payload 有机会运行之前将其阻止。
```
permissions:
contents: read
id-token: write
jobs:
build:
runs-on: ubuntu-latest
env:
MANTICORE_AUTH_MODE: github-oidc
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #6.0.2
- uses: TazarSec/ManticoreScanner/setup@v1
- run: manticore exec --fail-on 50 -- npm ci
- run: npm run build
```
支持的包管理器:`npm`。支持的子命令:`install`、`ci` 和 `install `。
#### 作为 workflow 步骤运行扫描
```
permissions:
contents: read
id-token: write
jobs:
scan:
runs-on: ubuntu-latest
env:
MANTICORE_AUTH_MODE: github-oidc
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #6.0.2
- uses: TazarSec/ManticoreScanner/setup@v1
- run: manticore scan --format sarif --output manticore.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: manticore.sarif
```
通过标志或 `MANTICORE_*` 环境变量配置运行时行为。参见下方的 [CLI](#cli)。
#### 输入
| 输入 | 描述 | 默认值 |
|---|---|---|
| `version` | 固定特定的发布标签(例如 `v1.2.3`)。 | 调用 action 时使用的引用(例如 `v1`) |
## CLI
### 安装
```
go install github.com/TazarSec/ManticoreScanner/cmd/manticore@latest
```
或者从源码构建:
```
git clone https://github.com/TazarSec/ManticoreScanner.git
cd ManticoreScanner
go build -o manticore ./cmd/manticore
```
同时还发布了预构建的发布二进制文件(`manticore--`)和 Docker 镜像。参见[验证发布构件](#verifying-release-artifacts)和 [Docker](#docker)。
### `manticore scan`
解析 npm lockfile(或 `package.json`)并将依赖项提交到后端进行行为分析。
#### 认证模式
CLI 支持两种认证模式,通过 `--auth-mode` 或 `MANTICORE_AUTH_MODE` 选择:
- **`api-key`(默认)** - 通过 `--api-key` 或 `MANTICORE_API_KEY` 传递的长期存活的 key。用于本地运行以及 GitHub Actions 之外的任何 CI。
- **`github-oidc`** - 从 GitHub Actions 的 OIDC 提供者(受众 `tazarsec.dev`)获取一个短期的 JWT。要求工作流授予 `permissions: id-token: write`;CLI 会自动读取 `ACTIONS_ID_TOKEN_REQUEST_URL` 和 `ACTIONS_ID_TOKEN_REQUEST_TOKEN`。[GitHub Action](#github-action) 封装器默认设置此模式。当您直接在 workflow 内部调用 CLI 时,只需传递 `--auth-mode github-oidc`。
如果在选择 `--auth-mode=github-oidc` 的同时设置了 `MANTICORE_API_KEY`,CLI 将忽略该 key 并打印警告。
#### 基本扫描
自动检测当前目录下的 `package-lock.json` 或 `package.json`:
```
manticore scan --api-key YOUR_API_KEY
```
#### 扫描特定文件
```
manticore scan --api-key YOUR_API_KEY --file path/to/package-lock.json
```
#### 输出格式
```
# 人类可读表格(默认)
manticore scan --api-key YOUR_API_KEY --format table
# JSON
manticore scan --api-key YOUR_API_KEY --format json
# SARIF(用于 GitHub Code Scanning)
manticore scan --api-key YOUR_API_KEY --format sarif --output results.sarif
```
#### 在发现可疑包时失败
默认情况下,如果任何包的可疑分数为 `1` 或更高(即任何非零发现),扫描将以非零状态退出。传递 `--fail-on N` 可提高阈值,仅在出现更强信号时才失败:
```
manticore scan --api-key YOUR_API_KEY --fail-on 50
```
默认阈值也可以通过 `MANTICORE_FAILURE_THRESHOLD` 环境变量覆盖。
#### 跳过 devDependencies
```
manticore scan --api-key YOUR_API_KEY --production
```
#### 传递依赖
默认情况下,扫描器只提交**直接**依赖(即 `package.json` 中 `dependencies` / `devDependencies` 里的条目)。后端的行为分析在安装每个直接包时已经执行了传递性代码,因此大多数“活体 payload”的供应链攻击都会被间接捕获。
如果您希望按名称提交解析树中的每个包,请选择启用:
```
manticore scan --api-key YOUR_API_KEY --include-transitive
```
权衡:这可能会在典型的 Node 项目中将您的扫描量增加 10–100 倍。除非您特别需要对传递依赖的静态信号覆盖,否则请将其关闭。
#### 忽略特定包
传递一个每行一个条目的文件。每个条目必须固定特定的发布版本,使用 `name@version` 或 lockfile 的完整性哈希(例如 `sha512-...`)。纯包名将被拒绝,因此忽略操作绝不会静默覆盖未来的恶意版本。空行和以 `#` 开头的行将被忽略。匹配的包在提交前被跳过,因此它们不会计入您的扫描配额。
哈希匹配会读取 `package-lock.json` 的 `integrity` 字段;`package.json` 中的条目没有哈希,只能通过 `name@version` 进行忽略。
```
manticore scan --api-key YOUR_API_KEY --ignore-list .manticoreignore
```
```
# .manticoreignore
lodash@4.17.21
@scope/internal-pkg@1.2.3
sha512-oRjE9PZkgGr/QJtKqz5IngnFFiLk5xQxQ4y+9k4dZB5RZ2yMJZ8R3pYV+Q0WQ1l7xq4j6+UqQc9Yj3o/4G0sUQ==
```
默认不使用忽略列表。
#### 将结果发布到 GitHub PR
当在 GitHub Actions 中运行时,向 PR 发布包含可疑包的评论:
```
manticore scan --api-key YOUR_API_KEY --vcs-comment
```
### `manticore exec`
封装包管理器的安装命令。在不运行安装脚本的情况下将依赖树解析为 lockfile,扫描每个包,并且只有在扫描通过时才继续进行真正的安装。
```
manticore exec -- npm ci
manticore exec -- npm install
manticore exec -- npm install lodash
manticore exec --fail-on 50 -- npm install
manticore exec --ignore-list .manticoreignore -- npm ci
manticore exec --on-error continue -- npm ci
```
支持的包管理器:`npm`。
`exec` 与 [`scan`](#fail-on-suspicious-packages) 共享相同的 `--fail-on` 默认值(`1` — 任何非零可疑分数都会阻止安装),并以相同的方式遵循 `MANTICORE_FAILURE_THRESHOLD`。传递 `--fail-on N`(或设置环境变量)以仅在更强信号时进行拦截,例如 `--fail-on 50` 在中等发现时阻止,或 `--fail-on 70` 仅在强发现时阻止。使用 `--ignore-list` 可放弃特定的固定包(格式与 [`scan`](#ignore-specific-packages) 相同)。使用 `--on-error continue` 可以在后端不可用或轮询截止时间已过仍有包处于待处理状态时继续安装 — 这是以安全性换取可用性。
## 环境变量
以下每个变量都是可选的,并且在同时设置了等效 CLI 标志时会被其覆盖。
| 变量 | 描述 | 默认值 |
|---|---|---|
| `MANTICORE_AUTH_MODE` | 认证模式:`api-key` 或 `github-oidc`。 | `api-key` |
| `MANTICORE_API_KEY` | API key(`--api-key` 的替代方案)。在 `MANTICORE_AUTH_MODE=api-key` 时使用。 | — |
| `MANTICORE_API_URL` | API 基础 URL。 | `https://tazarsec.dev` |
| `MANTICORE_TIMEOUT` | 轮询超时(秒)。 | `300` |
| `MANTICORE_HTTP_TIMEOUT` | 每次请求的 HTTP 超时(秒)。 | `120` |
| `MANTICORE_ON_ERROR` | 在后端出错或轮询截止时间已过仍有待处理项时的行为:`fail` 或 `continue`。 | `fail` |
| `MANTICORE_FORMAT` | 输出格式:`table`、`json`、`sarif`。 | `table` |
| `MANTICORE_FAILURE_THRESHOLD` | 未显式传递时的默认 `--fail-on` 阈值。 | `1`(任何非零分数都会失败) |
| `MANTICORE_IGNORE_LIST` | 忽略列表文件的路径(`--ignore-list` 的替代方案)。 | 无 |
| `MANTICORE_INCLUDE_TRANSITIVE` | 设置为 `true` 以提交传递依赖。 | `false`(仅限直接依赖) |
| `MANTICORE_INURE` | 设置为 `true` 以允许明文 `http://` API URL。 | `false`(需要 HTTPS) |
## Docker
每次发布时都会将多架构镜像(`linux/amd64`、`linux/arm64`)发布到 GHCR。标签:`vX.Y.Z`(不可变)、`vX`(主要版本线中的最新发布)和 `latest`。
```
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
ghcr.io/tazarsec/manticorescanner:latest \
scan --api-key YOUR_API_KEY
```
### 验证镜像签名
发布镜像通过 cosign 无密钥(Sigstore + GitHub OIDC)按摘要签名,并拥有推送到注册表的 SLSA 构建来源证明。
```
IMAGE=ghcr.io/tazarsec/manticorescanner:v1.2.3
# Cosign 无密钥签名
cosign verify "${IMAGE}" \
--certificate-identity-regexp '^https://github.com/TazarSec/ManticoreScanner/\.github/workflows/release\.yml@refs/tags/v.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
# SLSA 构建来源
gh attestation verify "oci://${IMAGE}" --repo TazarSec/ManticoreScanner
```
为了可重现的拉取,请按摘要而不是标签进行固定:
```
docker pull ghcr.io/tazarsec/manticorescanner@sha256:
```
## 验证发布构件
每次发布都会生成带有无密钥签名的 `checksums.txt`,以及每个二进制文件的 SLSA 构建来源证明:
1. **无密钥签名**(`checksums.txt.sig` / `checksums.txt.pem`)由发布工作流使用 [cosign](https://github.com/sigstore/cosign) + Sigstore Fulcio + GitHub OIDC 自动生成,并在 Rekor 中进行透明度记录。
2. 每一个 `manticore-*` 二进制文件的**构建来源证明**,通过 GitHub 的 [attest-build-provenance](https://github.com/actions/attest-build-provenance) 生成。
使用其中一种或两种进行验证:
```
# 1. 无密钥(Sigstore/OIDC)
cosign verify-blob \
--certificate checksums.txt.pem \
--signature checksums.txt.sig \
--certificate-identity-regexp '^https://github.com/TazarSec/ManticoreScanner/\.github/workflows/release\.yml@refs/tags/v.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
# 2. SLSA 构建来源
gh attestation verify manticore-linux-amd64 --repo TazarSec/ManticoreScanner
# 然后针对已验证的 manifest 验证二进制文件本身
sha256sum --check --ignore-missing checksums.txt
```
## 许可证
依据 [Apache License, Version 2.0](LICENSE) 许可(SPDX: `Apache-2.0`)。请参阅 [NOTICE](NOTICE) 了解归属信息。
标签:CI/CD安全, DevSecOps, EVTX分析, GitHub Action, Llama, LNA, Manticore, Node.js安全, npm安全, OIDC认证, TazarSec, Web截图, 上游代理, 云安全监控, 依赖安全, 包管理器安全, 容器安全, 日志审计, 暗色界面, 请求拦截, 静态分析