NVIDIA/SkillSpector
GitHub: NVIDIA/SkillSpector
NVIDIA 出品的 AI agent 技能安全扫描器,在安装前检测漏洞、恶意模式和安全风险。
Stars: 6201 | Forks: 453
# SkillSpector
**AI agent 技能的安全扫描器。** 在安装 agent 技能之前检测漏洞、恶意模式和安全风险。
[](https://www.python.org/downloads/)
[](https://www.apache.org/licenses/LICENSE-2.0)
## 概述
AI agent 技能(被 Claude Code、Codex CLI、Gemini CLI 等使用)在执行时被赋予了隐式信任,且缺乏足够的审查。研究表明,**26.1% 的技能包含漏洞**,并且 **5.2% 表现出可能的恶意意图**。
SkillSpector 帮助您回答:**“这个技能安装安全吗?”**
## 文档
- **[开发指南](docs/DEVELOPMENT.md)** — 架构、包布局以及如何扩展分析器 pipeline。
## 功能
- **多格式输入**:扫描 Git 仓库、URL、zip 文件、目录或单个文件
- **涵盖 16 个类别的 64 种漏洞模式**:prompt injection、数据泄露、权限提升、供应链、过度授权、输出处理、system prompt 泄露、memory poisoning、工具误用、恶意 agent、触发器滥用、危险代码 (AST)、taint tracking、YARA 签名、MCP 最小权限和 MCP 工具投毒
- **两阶段分析**:快速静态分析 + 可选的 LLM 语义评估
- **实时漏洞查询**:SC4 查询 [OSV.dev](https://osv.dev) 获取实时的 CVE 数据,并带有自动的离线兜底
- **多种输出格式**:终端、JSON、Markdown 和 SARIF 报告
- **风险评分**:0-100 分,带有严重程度标签和明确的建议
## 快速开始
### 安装
首先创建并激活一个虚拟环境(所有 `make` 目标都假定该虚拟环境已激活)。使用 **uv** 或 **pip**;如果可用,Makefile 会使用 `uv`,否则使用 `pip`。
```
# 克隆仓库
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
# 创建并激活虚拟环境
uv venv .venv && source .venv/bin/activate
# 或者:python3 -m venv .venv && source .venv/bin/activate
# 为生产使用安装
make install
# 或者安装开发依赖
make install-dev
```
### 基本用法
```
# 扫描本地 skill 目录
skillspector scan ./my-skill/
# 扫描单个 SKILL.md 文件
skillspector scan ./SKILL.md
# 扫描 Git 仓库
skillspector scan https://github.com/user/my-skill
# 扫描 zip 文件
skillspector scan ./my-skill.zip
```
### 输出格式
```
# 终端输出(默认)- 美化格式
skillspector scan ./my-skill/
# JSON 输出 - 机器可读
skillspector scan ./my-skill/ --format json --output report.json
# Markdown 输出 - 用于文档
skillspector scan ./my-skill/ --format markdown --output report.md
# SARIF 输出 - 用于 CI/CD 集成和 IDE 工具
skillspector scan ./my-skill/ --format sarif --output report.sarif
```
### LLM 分析
为了获得最佳结果,请为语义分析配置一个 OpenAI 兼容的 LLM endpoint。使用 `SKILLSPECTOR_PROVIDER` 选择一个提供商;每个提供商都内置了默认的 model。SkillSpector 也适用于本地 OpenAI 兼容服务器(Ollama、vLLM、llama.cpp)以及托管推理网关。
| Provider (`SKILLSPECTOR_PROVIDER`) | 凭据环境变量 | Endpoint | 默认 model |
|----------|----|----|----|
| `openai` | `OPENAI_API_KEY` (+ 可选的 `OPENAI_BASE_URL`) | api.openai.com (或任何 OpenAI 兼容的 URL) | `gpt-5.4` |
| `anthropic` | `ANTHROPIC_API_KEY` | api.anthropic.com | `claude-opus-4-6` |
| `nv_build` | `NVIDIA_INFERENCE_KEY` | build.nvidia.com | `deepseek-ai/deepseek-v4-flash` |
```
# Stock OpenAI
export SKILLSPECTOR_PROVIDER=openai
export OPENAI_API_KEY=sk-...
skillspector scan ./my-skill/
# Anthropic
export SKILLSPECTOR_PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
skillspector scan ./my-skill/
# NVIDIA build.nvidia.com
export SKILLSPECTOR_PROVIDER=nv_build
export NVIDIA_INFERENCE_KEY=nvapi-...
skillspector scan ./my-skill/
# 本地 Ollama 或任何兼容 OpenAI 的 endpoint
export SKILLSPECTOR_PROVIDER=openai
export OPENAI_API_KEY=ollama
export OPENAI_BASE_URL=http://localhost:11434/v1
export SKILLSPECTOR_MODEL=llama3.1:8b
skillspector scan ./my-skill/
# 覆盖 provider 的默认模型
export SKILLSPECTOR_MODEL=gpt-5.2
skillspector scan ./my-skill/
# 跳过 LLM 分析(更快,仅静态分析)
skillspector scan ./my-skill/ --no-llm
```
## 漏洞模式
SkillSpector 检测跨越 16 个类别的 **64 种漏洞模式**:
### Prompt Injection (5 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| P1 | 指令覆盖 | HIGH | 忽略安全约束的命令 |
| P2 | 隐藏指令 | HIGH | 注释/不可见文本中的恶意指令 |
| P3 | 泄露命令 | HIGH | 将上下文传输到外部的指令 |
| P4 | 行为操纵 | MEDIUM | 改变 agent 决策的隐秘指令 |
| P5 | 有害内容 | CRITICAL | 可能造成人身伤害的指令 |
### 数据泄露 (4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| E1 | 外部传输 | MEDIUM | 将数据发送到外部 URL |
| E2 | 环境变量收集 | HIGH | 收集 API 密钥和机密信息 |
| E3 | 文件系统枚举 | MEDIUM | 扫描目录以查找敏感文件 |
| E4 | 上下文泄露 | HIGH | 将会话上下文传输到外部 |
### 权限提升 (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| PE1 | 过度权限 | LOW | 请求超出既定功能的访问权限 |
| PE2 | Sudo/Root 执行 | MEDIUM | 调用提升的系统权限 |
| PE3 | 凭据访问 | HIGH | 读取 SSH 密钥、token、密码 |
### 供应链 (6 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| SC1 | 未锁定的依赖 | LOW | 软件包没有版本约束 |
| SC2 | 外部脚本获取 | HIGH | curl \| bash 以及远程代码执行 |
| SC3 | 混淆代码 | HIGH | Base64/十六进制编码执行 |
| SC4 | 已知漏洞依赖 | HIGH | 带有已知 CVE 的依赖项(实时 OSV.dev 查询) |
| SC5 | 废弃依赖 | MEDIUM | 缺乏安全更新的无人维护软件包 |
| SC6 | Typosquatting | HIGH | 与流行软件包相似的包名 |
### 过度授权 (4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| EA1 | 无限制工具访问 | HIGH | 无约束的、不受限制的工具访问 |
| EA2 | 自主决策 | HIGH | 没有 human-in-the-loop 的高影响决策 |
| EA3 | 范围蔓延 | MEDIUM | 能力扩展超出了既定目的 |
| EA4 | 无限制资源访问 | MEDIUM | 资源消耗没有速率限制或配额 |
### 输出处理 (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| OH1 | 未经验证的输出注入 | HIGH | 使用未经清理的 model 输出 |
| OH2 | 跨上下文输出 | MEDIUM | 输出未经校验跨越信任边界流动 |
| OH3 | 无限制输出 | MEDIUM | 对输出大小或生成速率没有限制 |
### System Prompt 泄露 (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| P6 | 直接泄露 | HIGH | 暴露 system prompt 或内部规则的指令 |
| P7 | 间接提取 | MEDIUM | 通过复述、翻译或侧信道进行提取 |
| P8 | 基于工具的泄露 | HIGH | 通过文件写入或网络请求泄露 system prompt |
### Memory Poisoning (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| MP1 | 持久化上下文注入 | HIGH | 旨在跨交互持久存在的内容 |
| MP2 | 上下文窗口塞入 | MEDIUM | 填充内容取代了安全约束 |
| MP3 | 记忆操纵 | HIGH | 篡改 agent 记忆或存储状态 |
### 工具误用 (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| TM1 | 工具参数滥用 | HIGH | 为实现非预期行为而构造的参数 (shell=True, --force) |
| TM2 | 链式滥用 | HIGH | 绕过单个安全检查的工具链 |
| TM3 | 不安全的默认值 | MEDIUM | 过于宽松的默认值(禁用 TLS、无身份验证) |
### 恶意 Agent (2 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| RA1 | 自我修改 | CRITICAL | 在 runtime 修改自身的代码或配置 |
| RA2 | 会话持久化 | HIGH | 通过 cron 作业或启动脚本进行未经授权的持久化 |
### 触发器滥用 (3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| TR1 | 过宽的触发器 | MEDIUM | 匹配常见词汇的触发器模式 |
| TR2 | 影子命令触发器 | HIGH | 掩盖内置命令或其他技能的触发器 |
| TR3 | 关键词诱导触发器 | MEDIUM | 旨在最大化激活率的通用触发器 |
### 行为 AST (8 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| AST1 | exec() 调用 | CRITICAL | 实现任意代码执行的直接 exec() |
| AST2 | eval() 调用 | HIGH | 计算任意表达式的直接 eval() |
| AST3 | 动态导入 | HIGH | 在 runtime 加载任意模块的 \_\_import\_\_() |
| AST4 | subprocess 调用 | HIGH | 通过 subprocess 执行外部命令 |
| AST5 | os.system / exec-family | HIGH | 通过 os 模块执行 Shell 命令 |
| AST6 | compile() 调用 | MEDIUM | 从字符串创建代码对象 |
| AST7 | 动态 getattr() | MEDIUM | 使用非字面量名称进行任意属性访问 |
| AST8 | 危险执行链 | CRITICAL | exec/eval 结合动态源(网络、编码数据) |
### Taint Tracking (5 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| TT1 | 直接污点流 | HIGH | 数据从源直接流向 sink 而未经清理 |
| TT2 | 变量介导的污点流 | MEDIUM | 数据通过中间变量从源流向 sink |
| TT3 | 凭据泄露链 | CRITICAL | 凭据(环境变量、机密)流向网络输出 sink |
| TT4 | 文件读取到网络泄露 | HIGH | 文件内容流向网络输出 sink |
| TT5 | 外部输入到代码执行 | CRITICAL | 网络或用户输入流向 exec/eval/subprocess sink |
### YARA 签名 (4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| YR1 | 恶意软件匹配 | CRITICAL | YARA 规则匹配到已知的恶意软件签名 |
| YR2 | Webshell 匹配 | CRITICAL | YARA 规则匹配到 webshell 模式 |
| YR3 | 加密挖矿程序匹配 | HIGH | YARA 规则匹配到加密挖矿指标 |
| YR4 | 黑客工具/漏洞利用匹配 | HIGH | YARA 规则匹配到黑客工具或漏洞利用代码 |
### MCP 最小权限 (4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| LP1 | 声明不足的能力 | HIGH | 代码使用了未在声明权限中列出的能力 |
| LP2 | 通配符权限 | MEDIUM | 权限列表包含通配符 (\*, all, full, any) |
| LP3 | 缺失权限声明 | MEDIUM | 没有权限字段,但代码具有可检测的能力 |
| LP4 | 声明过度的权限 | LOW | 声明了权限但未找到对应的代码能力 |
### MCP 工具投毒 (4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|----|---------|----------|-------------|
| TP1 | 隐藏指令 | HIGH | 元数据中的隐藏指令(HTML 注释、零宽字符、base64、data URI) |
| TP2 | Unicode 欺骗 | HIGH | 工具元数据中的同形字、RTL 覆盖、混合脚本标识符 |
| TP3 | 参数描述注入 | MEDIUM | 参数定义中的注入模式(覆盖、system token、恶意默认值) |
| TP4 | 描述与行为不符 | MEDIUM | 声明的工具描述与实际代码行为不符(LLM 驱动) |
上表列出了所有检测到的模式。
## 风险评分
### 评分计算
- **CRITICAL 问题**:+50 分
- **HIGH 问题**:+25 分
- **MEDIUM 问题**:+10 分
- **LOW 问题**:+5 分
- **可执行脚本**:1.3 倍乘数
### 严重程度级别
| 分数 | 严重程度 | 建议 |
|-------|----------|----------------|
| 0-20 | LOW | 安全 |
| 21-50 | MEDIUM | 谨慎 |
| 51-80 | HIGH | 请勿安装 |
| 81-100 |ITICAL | 请勿安装 |
## 输出示例
### 终端输出
```
SkillSpector Security Report v2.0.0
Skill: suspicious-skill
Source: ./suspicious-skill/
Scanned: 2026-01-29 10:30:00 UTC
Risk Assessment
Metric Value
Score 78/100
Severity HIGH
Recommendation DO NOT INSTALL
Components (3)
File Type Lines Executable
SKILL.md markdown 142 No
scripts/sync.py python 87 Yes
requirements.txt text 3 No
Issues (2)
HIGH: Env Variable Harvesting (E2)
Location: scripts/sync.py:23
Finding: for key, val in os.environ.items():...
Confidence: 94%
Explanation: This code collects environment variables containing
API keys and secrets, then sends them to an external server.
HIGH: External Transmission (E1)
Location: scripts/sync.py:45
Finding: requests.post("https://api.skill.io/env"...
Confidence: 89%
Explanation: Data is being sent to an external server. Combined
with env harvesting above, this indicates credential exfiltration.
```
## 配置
### 环境变量
| 变量 | 描述 | 必需 |
|----------|-------------|----------|
| `SKILLSPECTOR_PROVIDER` | 激活的 LLM provider:`openai`、`anthropic` 或 `nv_build`。每个 provider 都有自己的内置 `model_registry.yaml` 和默认 model(参见上方的 LLM 分析表格)。默认为 `nv_build`。 | 可选 |
| `NVIDIA_INFERENCE_KEY` | `nv_build` provider (build.nvidia.com) 的凭据。 | 当 `SKILLSPECTOR_PROVIDER=nv_build` 时 LLM 分析必需 |
| `OPENAI_API_KEY` | OpenAI provider (`SKILLSPECTOR_PROVIDER=openai`) 的凭据。在凭据瀑布中,当活动的 provider 未返回凭据时,它也作为第二级兜底。 | 当 `SKILLSPECTOR_PROVIDER=openai` 时 LLM 分析必需 |
| `OPENAI_BASE_URL` | 覆盖 OpenAI endpoint(例如指向 Ollama)。 | 可选 |
| `ANTHROPIC_API_KEY` | Anthropic provider (`SKILLSPECTOR_PROVIDER=anthropic`) 的凭据。 | 当 `SKILLSPECTOR_PROVIDER=anthropic` 时 LLM 分析必需 |
| `SKILLSPECTOR_MODEL` | 覆盖活动 provider 的默认 model。有关每个 provider 的默认值,请参见 LLM 分析表格。 | 可选 |
| `SKILLSPECTOR_MODEL_REGISTRY` | 使用自定义路径覆盖内置的各 provider YAML 注册表 (`src/skillspector/providers/.yaml`)。 | 可选 |
| `SKILLSPECTOR_LOG_LEVEL` | 日志级别:`DEBUG`、`INFO`、`WARNING`、`ERROR`(默认:`WARNING`)。 | 可选 |
### CLI 选项
```
skillspector scan --help
Options:
-f, --format [terminal|json|markdown|sarif] Output format [default: terminal]
-o, --output PATH Output file path
--no-llm Skip LLM analysis (static only)
-V, --verbose Show detailed progress
--help Show this message and exit
```
## 开发
### 设置
所有 `make` 目标都假定虚拟环境已经创建并激活。如果可用,Makefile 会使用 **uv**,否则使用 **pip**。
```
# 克隆,创建 venv,激活,安装开发依赖
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
uv venv .venv && source .venv/bin/activate
# 或者:python3 -m venv .venv && source .venv/bin/activate
make install-dev
# 运行测试
make test
# 运行测试并生成覆盖率
make test-cov
# 运行 linting
make lint
# 格式化代码
make format
```
## 工作原理
SkillSpector 使用双阶段检测 pipeline:
### 阶段 1:静态分析
- 跨越 11 个静态分析器进行快速的基于 regex 的模式匹配
- 基于 AST 的行为分析,检测危险调用(exec、eval、subprocess 等)
- 通过 OSV.dev 实时查询依赖项中已知的 CVE
- 扫描技能中的所有文件
- 高召回率(捕获大多数问题)
- 中等精准度(存在一些误报)
### 阶段 2:LLM 语义分析(可选)
- 评估上下文和意图
- 过滤误报
- 提供人类可读的解释
- 将精准度提高到 ~87%
LLM prompt 包含反越狱保护,以防止恶意技能操纵分析结果。
## 实时漏洞查询 (SC4)
SC4 使用 [OSV.dev](https://osv.dev) API 根据完整的开源漏洞数据库检查依赖项——涵盖了跨 PyPI 和 npm 的数以万计的安全通告。
- **无需 API 密钥** — OSV.dev 是免费且无需身份验证的。
- **批量查询** — 所有依赖项都在一次 HTTP 调用中完成检查。
- **自动兜底** — 如果无法访问 OSV.dev(物理隔离/离线状态),将使用小型的内置兜底列表。
- **缓存** — 结果会在内存中缓存 1 小时,以避免在会话期间进行多余的 API 调用。
该工具需要向外的 HTTPS 访问权限以连接到 `api.osv.dev` 获取实时漏洞数据。当不可用时,检测结果将仅限于静态兜底列表。
## 限制
- **非英语内容**:可能会漏掉其他语言中的模式
- **基于图像的攻击**:无法分析图像中的文本
- **加密/二进制代码**:无法分析编译或加密的内容
- **Runtime 行为**:仅限静态分析,无动态执行
- **离线 SC4**:如果没有对 `api.osv.dev` 的网络访问权限,SC4 将使用较小的静态兜底列表
## 研究背景
基于《Agent Skills in the Wild: An Empirical Study of Security Vulnerabilities at Scale》(Liu 等人,2026)的研究:
- **数据集**:来自主要市场的 42,447 项技能
- **易受攻击**:26.1% 包含至少一个漏洞
- **高严重性**:5.2% 表现出可能的恶意意图
- **关键发现**:带有可执行脚本的技能出现漏洞的可能性高出 2.12 倍
## Python API 集成
```
from skillspector import graph
# 调用 LangGraph workflow
result = graph.invoke({
"input_path": "/path/to/skill",
"output_format": "json", # terminal, json, markdown, or sarif
"use_llm": True, # False for static-only analysis
})
# 访问结果
print(f"Risk Score: {result['risk_score']}/100")
print(f"Severity: {result['risk_severity']}")
print(f"Recommendation: {result['risk_recommendation']}")
for finding in result["filtered_findings"]:
print(f"[{finding['severity']}] {finding['rule_id']}: {finding['message']}")
```
## 许可证
Apache License 2.0 - 详情请参阅 [LICENSE](LICENSE)。
## 贡献
欢迎贡献!请阅读我们的贡献指南并提交 pull request。
## 支持
- **问题**:[GitHub Issues](https://github.com/NVIDIA/skillspector/issues)
标签:AI安全, Chat Copilot, CISA项目, DLL 劫持, Petitpotam, Python, 大语言模型, 无后门, 逆向工具, 错误基检测, 静态代码分析