Su1ph3r/vercelsior
GitHub: Su1ph3r/vercelsior
Vercelsior 是一款针对 Vercel 平台的安全扫描器和配置审计工具。
Stars: 5 | Forks: 1
# Vercelsior
**Vercel 的开源安全扫描器和配置审计工具。**
[](https://github.com/Su1ph3r/vercelsior/actions/workflows/ci.yml)
[](https://github.com/Su1ph3r/vercelsior/actions/workflows/release.yml)
[](LICENSE)
[](https://goreportcard.com/report/github.com/Su1ph3r/vercelsior)
Vercelsior 对于 Vercel 来说,就像 [Prowler](https://github.com/prowler-cloud/prowler) 对于 AWS 和 [ScoutSuite](https://github.com/nccgroup/ScoutSuite) 对于多云一样。它审计您的 Vercel 账户、团队和项目配置,以查找安全配置错误、合规性差距和攻击面暴露。
单个二进制文件。零依赖。Linux、macOS、Windows。
*如果您是在 2026 年 4 月的 [Vercel 安全事件](https://vercel.com/kb/bulletin/vercel-april-2026-security-incident) 之后来到这里的,请参阅 `CHECK_REFERENCE.md` 了解适用的检查。*
## 模式
Vercelsior 从三个角度测试 Vercel 的安全性,每个角度都有自己的子命令:
| 命令 | 输入 | 视角 | 状态 |
|------|-------|-------------|--------|
| `vercelsior scan` | API 令牌 | **CSPM** — 从内部审计账户/团队/项目配置 | ✅ 可用 |
| `vercelsior probe ` | 一个 URL | **DAST** — 从外部黑盒测试已部署的站点(CVE-2025-29927 中间件绕过、源映射、头部卫生),无需令牌 | ✅ 可用 |
| `vercelsior project [path]` | 本地存储库 | **IaC/SAST** — 扫描 `vercel.json`、`next.config.*`、`package.json`、`.env*` 预部署,无需令牌 | ✅ 可用 |
运行 `vercelsior` 而不带子命令(或带有前导标志,例如 `vercelsior --token ...`)是 `vercelsior scan` 的别名,因此现有的使用和 CI 管道不受影响。这三个模式共同测试 Vercel 的安全性,从 **内部**(令牌)、**存储库**(预部署)和 **外部**(已部署的 URL)——这是唯一一个能够做到这三点的工具。
### 项目模式(本地 IaC/SAST)
在部署前扫描项目存储库——无需令牌,在每次 PR 上运行 CI:
```
vercelsior project ./my-app
vercelsior project . -f sarif -o ./results # GitHub code scanning on PRs
```
检查:**Next.js CVE** 矩阵与 `package.json` 中的 `next` 版本(包括 CVE-2025-29927),`.env*` 中的 **已提交/客户端暴露的秘密**(硬编码值、`NEXT_PUBLIC_`/`VITE_`/等泄漏、`.gitignore` 覆盖率)、危险的 **`next.config.*`** 标志(`productionBrowserSourceMaps`、`ignoreBuildErrors`、`ignoreDuringBuilds`、`poweredByHeader`)和 **`vercel.json`** 问题(外部重定向/重写、缺少安全头部)。
### 探测模式(黑盒 DAST)
从外部测试已部署的 URL——无需令牌,攻击者的视角:
```
vercelsior probe https://my-app.vercel.app
vercelsior probe my-app.vercel.app/dashboard -f sarif -o ./results
```
检查:**CVE-2025-29927** Next.js 中间件身份验证绕过(发送 `x-middleware-subrequest` 头部,仅在阻止基线翻转到 2xx 时报告发现——没有虚假声明),暴露的 JavaScript **源映射**(`/_next/static/**/*.js.map`)、**安全头部**(CSP、HSTS、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy)和 **技术披露**(`X-Powered-By`)。所有出口都通过与 `--live` 相同的 SSRF 守护、重定向固定的客户端运行,对发现的 URL 执行相同主机的强制措施。
## 发现内容
**三个模式中的 160 多项检查**——`scan` 模式中的 140 多项账户/团队检查(以下 20 个类别),以及 [其部分](#modes) 中列出的 `probe`(DAST)和 `project`(IaC/SAST)检查,以及详细说明在 `CHECK_REFERENCE.md`(./CHECK_REFERENCE.md) 中。
`scan` 模式(CSPM)涵盖:
- 泄露的 API 令牌、无过期令牌、过权限范围
- 禁用的 WAF/防火墙、缺少 OWASP 规则、无速率限制
- `NEXT_PUBLIC_` 环境变量泄露秘密到客户端 JavaScript
- 以纯文本形式存储或暴露给预览环境的敏感凭证
- 运行已知 CVE 版本的 Next.js 部署(CVE-2025-29927、CVE-2025-55182、CVE-2025-49826、CVE-2025-59471、CVE-2025-59472)
- 指向内部 IP 或云元数据的重写/重定向目标中的 SSRF 检测
- 通过框架前缀(VITE_、GATSBY_、REACT_APP_、NUXT_PUBLIC_)暴露的客户端暴露的秘密
- 仅提供检测模式的 WAF 规则,不提供活动保护
- 指向 Vercel IP 的悬空 A 记录,启用子域接管
- 缺少签名的 Webhook 终端
- 来自悬空 CNAME 和孤儿别名子域接管的风险
- 缺少部署保护、未受保护的预览 URL、禁用的分支保护
- 没有日志导出、没有 Webhook、没有安全事件监控
- 通过实时 HTTP 探测缺少安全头部(CSP、HSTS、X-Frame-Options)
- 未受保护的可视化映射暴露原始源代码
- 缺少 SPF、DMARC、CAA 和 DNSSEC 记录
- 弱 TLS 证书、缺少后端连接的 mTLS
- 开放的重定向、通配符路由代理到外部来源
- Vercel 存储(KV、Postgres、Blob)凭证在预览环境中
- 缺少 CRON_SECRET 验证的未受保护的 cron 作业终端
每个发现都包括:
- **风险评分**(1-10)以及解释评分的书面理由
- **概念证明证据**,显示实际的 API 请求和响应,以证明配置错误
- **验证命令**(curl/CLI)以独立确认发现
- **修复命令**和文档链接
## 安装
### Go 安装
```
go install github.com/Su1ph3r/vercelsior/cmd/vercelsior@latest
```
### 二进制文件下载
Linux(amd64/arm64)、macOS(amd64/arm64)和 Windows(amd64)的预构建二进制文件可在 [发布](https://github.com/Su1ph3r/vercelsior/releases) 页面上找到。
### Homebrew(macOS / Linux)
```
brew install Su1ph3r/tap/vercelsior
```
### Scoop(Windows)
```
scoop bucket add su1ph3r https://github.com/Su1ph3r/scoop-bucket
scoop install vercelsior
```
### Docker
```
docker run --rm -e VERCEL_TOKEN ghcr.io/su1ph3r/vercelsior --min-severity HIGH
```
### 从源代码构建
```
git clone https://github.com/Su1ph3r/vercelsior.git
cd vercelsior
make build # or: go build -o vercelsior ./cmd/vercelsior/
```
## 快速入门
```
# --- 扫描(账户CSPM,需要令牌)---
export VERCEL_TOKEN="your-api-token"
vercelsior scan # run all checks (bare `vercelsior` also works)
vercelsior scan --team-slug my-team # scope to a team
vercelsior scan --min-severity HIGH # only critical + high findings
vercelsior scan --live # add live security-header probing
vercelsior scan -f html -o ./reports # HTML report only
vercelsior scan --diff ./reports/prev.json # compare with a previous scan
# --- 探测(黑盒DAST,无需令牌)---
vercelsior probe https://my-app.vercel.app
# --- 项目(本地IaC/SAST,无需令牌)---
vercelsior project ./my-app
```
## 令牌权限
在 **Vercel 仪表板 > 设置 > 令牌** 中创建令牌:
- **读取**所有资源的访问权限
- 如果扫描团队,则 **团队**范围
Vercelsior 从不写入或修改您的 Vercel 配置。如果令牌缺少对某些端点的权限,则报告中将产生明确的拒绝访问发现,并打印跳过的端点摘要。
## 输出格式
### HTML 报告
交互式深色主题报告,包括:
- 姿态评分环(0-100)
- 按类别分组、按严重性排序的发现
- 可折叠的发现,包括 PoC 证据、验证命令和修复
- 通过状态(失败/警告/通过)过滤
### JSON 报告
可机器读取的输出,包含完整的发现数据,包括风险评分、PoC 证据(请求+响应)、修复命令和资源详细信息。设计用于 CI/CD 集成和 SIEM 吸收。
### Markdown 报告
适用于拉取请求、维基和文档的便携式文本报告。
### SARIF 报告
[SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) 输出,用于 **GitHub Code Scanning** 和通用 SAST 工具。发现出现在存储库的 **安全 → 代码扫描** 选项卡中,每个发现的 `security-severity` 评分(由 Vercelsior 的 1-10 风险评分驱动)和稳定的指纹,以便在扫描中持久化发现不会作为新发现重新报告。
```
vercelsior -f sarif -o ./results
```
### 扫描差异
比较两个扫描以跟踪修复进度:
```
vercelsior --diff ./previous-scan.json
```
以 Markdown 和 JSON 格式输出新发现、已解决发现和姿态评分差异。
## CLI 参考信息
```
vercelsior [options]
vercelsior [options] # alias for 'scan' (legacy form)
Commands:
scan Audit a Vercel account/team via the API (CSPM)
probe Black-box test a deployed Vercel URL (no token)
project Scan a local Vercel project (no token, pre-deploy)
version Print the version
help Show help; 'help ' for command options
```
以下选项适用于 `scan`(以及旧版裸形式)。
| 标志 | 描述 |
|------|-------------|
| `-t`,`--token` | Vercel API 令牌(或 `VERCEL_TOKEN` 环境变量) |
| `--team-id` | 通过 ID 范围到团队 |
| `--team`,`--team-slug` | 通过 slug 范围到团队 |
| `-o`,`--output` | 输出目录(默认:当前目录) |
| `-f`,`--format` | 以逗号分隔:`html`、`json`、`md`、`sarif`(默认:`html,json,md`) |
| `--live` | 启用针对生产域的实时 HTTP 头部探测 |
| `--min-severity` | 报告的最小严重性:`CRITICAL`、`HIGH`、`MEDIUM`、`LOW`、`INFO` |
| `--checks` | 仅运行这些检查 ID(以逗号分隔) |
| `--skip-checks` | 跳过这些检查 ID(以逗号分隔) |
| `--category` | 仅运行这些类别(以逗号分隔) |
| `--no-color` | 禁用彩色终端输出 |
| `-c`,`--config` | 配置文件路径(默认:`.vercelsior`) |
| `--diff` | 与之前的 JSON 报告进行比较 |
| `--record` | 将 API 响应记录到目录(用于离线测试) |
| `--replay` | 从目录中回放 API 响应(离线模式) |
| `-v`,`--version` | 显示版本 |
| `-h`,`--help` | 显示帮助 |
### 退出代码
| 代码 | 含义 |
|------|---------|
| `0` | 所有检查都通过(或过滤到 `--min-severity` 以下) |
| `2` | 一个或多个发现达到或超过严重性阈值 |
## 配置文件
Vercelsior 从当前目录(或 `--config` 给出的路径)读取 `.vercelsior`。
```
# 抑制已接受的风险
suppress: iam-015
suppress: dom-010
# 严重性阈值
min_severity: HIGH
# 跳过类别
skip_category: Infrastructure
skip_category: Sandboxes
# 仅运行特定检查
check: njs-001
check: sec-001
```
CLI 标志覆盖配置文件值。
## 检查类别
| 类别 | 检查 | 描述 |
|------|--------|-------------|
| 身份与访问管理 | 13 | API 令牌、SSO/SAML、团队角色、访问组 |
| 防火墙与 WAF | 11+ | OWASP CRS、管理规则、机器人保护、速率限制、IP 规则、检测模式 |
| 秘密与环境变量 | 11 | 纯文本检测、NEXT_PUBLIC_ 泄露、客户端暴露前缀、熵分析、跨环境暴露 |
| 部署保护 | 12 | 分支保护、源映射、部署网关、Node.js 版本、CORS |
| 域与证书 | 12 | 验证、到期、DNS 卫生、SPF/DMARC/CAA/DNSSEC、传输锁定 |
| 日志与监控 | 9 | 日志导出、Webhook、Webhook 签名、安全事件覆盖、审计事件 |
| 集成 | 6 | 权限范围、陈旧性、项目级访问 |
| 基础设施 | 8 | 安全计算、边缘配置、远程缓存、静态 IP |
| 预览与构建安全 | 6 | 预览保护、构建命令注入、部署钩子、绕过秘密 |
| 框架安全 | 3 | NEXT_PUBLIC_ 秘密、Next.js CVE 检测、框架识别 |
| 子域接管 | 3 | 悬空 CNAME 检测、悬空 A 记录检测、孤儿别名检测 |
| Git 与源代码管理 | 3 | 个人与组织存储库、受保护的范围、分支过滤 |
| 功能标志 | 2 | 安全敏感的标志名称、生产覆盖 |
| 证书与 TLS | 3 | 证书到期、弱密钥算法、mTLS |
| 路由与重定向 | 4 | 开放的重定向、外部来源代理、通配符路由、SSRF 检测 |
| 安全头部 | 6 | CSP、HSTS、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy |
| 存储 & 数据 | 3 | Vercel KV/Postgres/Blob 访问控制、cron 作业保护 |
| 滚动发布 | 2 | 审批网关、监控验证 |
| 沙盒 | 2 | 网络策略、陈旧性 |
| 部署验证 | 3 | 检查覆盖率、橡皮图章检测、重新运行滥用 |
有关带有 ID、风险评分和描述的完整检查列表,请参阅CHECK_REFERENCE.md](CHECK_REFERENCE.md)。
## 评分
**每个发现的风险评分(1-10):** 根据针对 Vercel 平台的利用性、影响和可能性分配。每个评分都包括书面理由。
**姿态评分(0-100):** 作为所有发现的加权风险计算。失败发现贡献完整风险评分,警告发现贡献一半。干净的账户得分为 100。
```
posture = 100 - (sum_of_fail_scores + sum_of_warn_scores * 0.5) / (total_checks * 10) * 100
```
## CI/CD 集成
### GitHub Actions
```
name: Vercel Security Audit
on:
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- name: Install
run: go install github.com/Su1ph3r/vercelsior/cmd/vercelsior@latest
- name: Scan
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: vercelsior --team-slug my-team --min-severity HIGH -f json,html -o ./results
- name: Upload Report
if: always()
uses: actions/upload-artifact@v4
with:
name: vercelsior-report
path: ./results/
```
将 `--min-severity CRITICAL` 设置为仅在关键发现上失败。
### GitHub 代码扫描(SARIF)
直接在存储库的 **安全** 选项卡中显示发现:
```
name: Vercel Security Audit
on:
schedule:
- cron: "0 6 * * 1"
workflow_dispatch:
permissions:
security-events: write # required to upload SARIF
jobs:
audit:
runs-on: ubuntu-latest
steps:
- name: Scan
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
docker run --rm -e VERCEL_TOKEN -v "$PWD/results:/results" \
ghcr.io/su1ph3r/vercelsior --team-slug my-team -f sarif -o /results
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ./results
```
## 测试
Vercelsior 包含用于离线测试的 API 记录/回放系统:
```
# 记录真实的API响应
vercelsior --token TOKEN --record test/fixtures/baseline
# 针对记录的响应离线运行
vercelsior --replay test/fixtures/baseline
# 运行集成测试
go test ./test/integration/ -v
```
有关完整的测试设置指南,请参阅 [test/README.md](test/README.md)。
## 贡献
1. 从存储库分叉并创建分支
2. 运行测试:`go test ./...`
3. 在 `internal/checks/` 中遵循现有的检查模块约定
4. 提交拉取请求
对于较大的更改,请先提出问题。
## 许可证
[MIT](LICENSE)
标签:API令牌, CSPM, CVE, DAST, EVTX分析, IaC/SAST, OSV, Prowler, ScoutSuite, TinkerPop, Vercel, 中间件绕过, 单文件程序, 头部安全, 子域名接管, 安全事件响应, 安全合规, 安全漏洞检测, 开源安全扫描, 恶意软件分析, 攻击面评估, 数字签名, 日志审计, 源映射, 网络代理, 零依赖