33 KiB
Note
本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
SkillSpector
面向 AI agent skill 的安全扫描器。 在安装 agent skill 之前,检测漏洞、恶意模式和安全风险。
概述
AI agent skill(供 Claude Code、Codex CLI、Gemini CLI 等使用)在隐式信任且几乎不经审核的情况下执行。研究表明,26.1% 的 skill 含有漏洞,5.2% 表现出明显的恶意意图。
SkillSpector 帮助你回答:「这个 skill 安装起来安全吗?」
文档
功能特性
- 多格式输入:可扫描 Git 仓库、URL、zip 文件、目录或单个文件
- 68 种漏洞模式,覆盖 17 个类别:提示注入(prompt injection)、数据渗出(data exfiltration)、权限提升(privilege escalation)、供应链(supply chain)、过度代理(excessive agency)、输出处理(output handling)、系统提示泄露(system prompt leakage)、记忆投毒(memory poisoning)、工具滥用(tool misuse)、失控 agent(rogue agent)、反拒答(anti-refusal)、触发器滥用(trigger abuse)、危险代码(AST)、污点追踪(taint tracking)、YARA 签名、MCP 最小权限(MCP least privilege)以及 MCP 工具投毒(MCP tool poisoning)
- 两阶段分析:快速静态分析 + 可选的 LLM 语义评估
- 实时漏洞查询:SC4 查询 OSV.dev 获取实时 CVE 数据,并自动离线回退
- 多种输出格式:终端、JSON、Markdown 和 SARIF 报告
- 风险评分:0-100 分,附严重程度标签和明确建议
- 基线 / 误报抑制:通过 glob 规则或指纹基线接受已知发现项,使重新扫描仅暴露新问题(文档)
快速入门
安装
请先创建并激活虚拟环境(所有 make 目标均假定 venv 已激活)。使用 uv 或 pip;Makefile 在可用时使用 uv,否则使用 pip。
使用 uv 快速安装(仅 CLI):
uv tool install git+https://github.com/NVIDIA/skillspector.git
# Update later: uv tool update skillspector
如果你计划运行 skillspector mcp,请在安装时一并安装 MCP 扩展:
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
从源码安装:
# Clone the repository
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
# Create and activate virtual environment
uv venv .venv && source .venv/bin/activate
# or: python3 -m venv .venv && source .venv/bin/activate
# Install for production use
make install
# Or install with development dependencies
make install-dev
Docker(无需 Python)
无需安装 Python 即可运行 SkillSpector:根据随附的 Dockerfile 在本地构建。镜像基于 Docker 官方 Python 3.12-slim-bookworm 镜像。
构建镜像:
make docker-build
# or: docker build -t skillspector .
扫描本地目录:将当前目录挂载到 /scan(容器工作目录):
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
启用 LLM 分析扫描:通过本地 .env 文件传入凭据:
cat > .env <<'EOF'
SKILLSPECTOR_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
EOF
docker run --rm \
-v "$PWD:/scan" \
--env-file .env \
skillspector scan ./my-skill/
或直接从 shell 环境传入凭据:
docker run --rm \
-v "$PWD:/scan" \
-e SKILLSPECTOR_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
skillspector scan ./my-skill/
将报告写入宿主机文件系统:写入已挂载的目录:
docker run --rm \
-v "$PWD:/scan" \
skillspector scan ./my-skill/ --no-llm --format json --output report.json
可选别名,用于重复的静态扫描:
alias skillspector-docker='docker run --rm -v "$PWD:/scan" skillspector'
skillspector-docker scan ./my-skill/ --no-llm
基本用法
# Scan a local skill directory
skillspector scan ./my-skill/
# Scan a single SKILL.md file
skillspector scan ./SKILL.md
# Scan a Git repository
skillspector scan https://github.com/user/my-skill
# Scan a zip file
skillspector scan ./my-skill.zip
输出格式
# Terminal output (default) - pretty formatted
skillspector scan ./my-skill/
# JSON output - machine readable
skillspector scan ./my-skill/ --format json --output report.json
# Markdown output - for documentation
skillspector scan ./my-skill/ --format markdown --output report.md
# SARIF output - for CI/CD integration and IDE tooling
skillspector scan ./my-skill/ --format sarif --output report.sarif
批量扫描
从 contrib/batch_scan/ 并行扫描整个 skill 目录:
python -m contrib.batch_scan.batch_scan ./my-skills/ --no-llm
python -m contrib.batch_scan.batch_scan ./my-skills/ --workers 20 -f json -o report.json
python -m contrib.batch_scan.batch_scan ./tests/fixtures/ -f terminal --workers 20
支持多语言检测(zh/ja/ko)以及终端/JSON/Markdown 输出。
对于需要更高并发的 LLM 扫描,请按
.env.example 配置多个 API 密钥 — 只要这些密钥不共享账户级速率限制,密钥池即可提升吞吐量和容错能力。
详见 contrib 指南。
关于 LLM 支持的说明: 默认配置以 DeepSeek 为目标, 作为最便宜的公开选项。DeepSeek-Chat 预计将于 expected to sunset, 下线,且贡献者 没有硬件可在本地模型上测试。批量扫描器最初使用 OpenAI 兼容端点进行测试 — DeepSeek 缺乏 结构化输出支持,因此需要手动 JSON 解析补丁。如果你能贡献更通用的后端(Ollama、vLLM 或其他提供商), 非常欢迎提交 PR。
抑制误报(基线)
抑制已知/已接受的发现项,使风险评分仅反映未分类的问题, 重新扫描仅暴露新发现项。完整参考见 抑制指南。
# Accept all current findings into a baseline (run once), then commit it.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml
# Scan against the baseline — only NEW findings are reported and scored.
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
# Review what was suppressed (still excluded from the score).
skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed
基线也可使用容差 glob 规则(按规则 id、文件路径或
消息)— 参见 .skillspector-baseline.example.yaml。
LLM 分析
为获得最佳效果,请配置 OpenAI 兼容的 LLM 端点以进行
语义分析。使用 SKILLSPECTOR_PROVIDER 选择提供商;每个
提供商都自带捆绑的默认模型。SkillSpector 也可对接
本地 OpenAI 兼容服务器(Ollama、vLLM、llama.cpp)以及托管
推理网关。
Provider (SKILLSPECTOR_PROVIDER) |
Credential env var | Endpoint | Default model |
|---|---|---|---|
openai |
OPENAI_API_KEY (+ optional OPENAI_BASE_URL) |
api.openai.com (or any OpenAI-compatible URL) | gpt-5.4 |
anthropic |
ANTHROPIC_API_KEY |
api.anthropic.com | claude-opus-4-6 |
anthropic_proxy |
ANTHROPIC_PROXY_API_KEY + ANTHROPIC_PROXY_ENDPOINT_URL |
Any Vertex-style raw-predict proxy | claude-sonnet-4-6 |
bedrock |
AWS_PROFILE (optional) + AWS_REGION — SigV4 via boto3 |
AWS Bedrock Runtime | us.anthropic.claude-sonnet-4-6-20250915-v1:0 |
nv_build |
NVIDIA_INFERENCE_KEY |
build.nvidia.com | deepseek-ai/deepseek-v4-flash |
claude_cli |
(none — uses local CLI auth) | local claude binary |
claude-sonnet-4-6 |
codex_cli |
(none — uses local CLI auth) | local codex binary |
o4-mini |
# 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/
# Anthropic via Vertex-style proxy (corporate gateways, GCP Vertex AI)
export SKILLSPECTOR_PROVIDER=anthropic_proxy
export ANTHROPIC_PROXY_ENDPOINT_URL=https://my-gateway.example.com/models/claude-sonnet-4-6:streamRawPredict
export ANTHROPIC_PROXY_API_KEY=your-bearer-token
export SKILLSPECTOR_MODEL=claude-sonnet-4-6
skillspector scan ./my-skill/
# AWS Bedrock (Claude via SigV4)
export SKILLSPECTOR_PROVIDER=bedrock
# Optional: select an AWS named profile. When unset, the standard
# boto3 credential chain (env vars, instance metadata, SSO, etc.) resolves.
# export AWS_PROFILE=my-profile
export AWS_REGION=us-west-2 # default if unset
# Default model: us.anthropic.claude-sonnet-4-6-20250915-v1:0
# Override with any Bedrock model ID, cross-region inference-profile
# ID, or your own application-inference-profile ARN:
# export SKILLSPECTOR_MODEL=us.anthropic.claude-opus-4-6-20250915-v1:0
skillspector scan ./my-skill/
# NVIDIA build.nvidia.com
export SKILLSPECTOR_PROVIDER=nv_build
export NVIDIA_INFERENCE_KEY=nvapi-...
skillspector scan ./my-skill/
# Local Claude CLI — no API key; uses your existing `claude auth login` session
# Requires: claude CLI installed and authenticated (claude auth login)
export SKILLSPECTOR_PROVIDER=claude_cli
skillspector scan ./my-skill/
# Local Codex CLI — no API key; uses your existing `codex login` session
# Requires: codex CLI installed and authenticated
export SKILLSPECTOR_PROVIDER=codex_cli
skillspector scan ./my-skill/
# Local Ollama or any OpenAI-compatible 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/
# Override the provider's default model
export SKILLSPECTOR_MODEL=gpt-5.2
skillspector scan ./my-skill/
# Skip LLM analysis (faster, static analysis only)
skillspector scan ./my-skill/ --no-llm
MCP Server
将 SkillSpector 作为 Model Context Protocol(MCP) 服务器运行,使任何支持 MCP 的代理(Claude Code、Codex CLI、Gemini CLI)或远程运行时都能将扫描作为工具调用,并根据扫描结果拦截 skill/MCP 安装——将 SkillSpector 从带外审计步骤转变为运行时护栏。
skillspector mcp 需要 skillspector[mcp]。
# Install, or reinstall if you already used the CLI-only path
uv tool install --force 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git'
# FastMCP stdio transport for local CLI agents
skillspector mcp
# streamable HTTP/SSE transport for remote / A2A callers
skillspector mcp --transport http --host 127.0.0.1 --port 8000
stdio 传输是当前面向本地 CLI 代理的 FastMCP 路径,issue #199 中报告的 initialize 挂起问题在该路径上仍然适用。
该服务器公开单个工具:
scan_skill(target, use_llm=true, output_format="json")— 扫描 Git URL、file URL、.zip、.md文件或目录,并返回结构化 判定结果:risk_score(0-100)、severity、recommendation、safe_to_install以及findings。它还会报告llm_used/scan_mode, 从而避免将仅静态扫描的低分误判为完整扫描通过。
通过以下方式在 Claude Code 中注册:
claude mcp add skillspector -- skillspector mcp
安全 — HTTP 传输信任模型
HTTP 传输未内置身份验证。任何能访问该端口的调用方都可以调用
scan_skill。通过 stdio 或127.0.0.1时, 这与 CLI 处于相同的信任边界。若绑定到可路由接口:
- 在对外暴露之前,将服务器置于带身份验证的反向代理之后(例如 nginx + mTLS)。
- 通过 HTTP 时,本地路径和
file://URL 会被自动拒绝, 以防止未经身份验证的调用方读取任意主机文件。仅接受远程 Git 和.zipURL。
漏洞模式
SkillSpector 在 17 个类别中检测 68 种漏洞模式:
提示注入(Prompt Injection,5 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| P1 | 指令覆盖(Instruction Override) | HIGH | 要求忽略安全约束的命令 |
| P2 | 隐藏指令(Hidden Instructions) | HIGH | 注释/不可见文本中的恶意指令 |
| P3 | 外泄命令(Exfiltration Commands) | HIGH | 要求将上下文向外传输的指令 |
| P4 | 行为操纵(Behavior Manipulation) | MEDIUM | 微妙地改变代理决策的指令 |
| P5 | 有害内容(Harmful Content) | CRITICAL | 可能导致人身伤害的指令 |
反拒绝(Anti-Refusal,3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| AR1 | 拒绝抑制(Refusal Suppression) | HIGH | 要求永不拒绝或始终服从的指令(例如 "never refuse"、"always comply") |
| AR2 | 免责声明抑制(Disclaimer Suppression) | HIGH | 要求省略警告、免责声明或伦理评注的指令(例如 "no disclaimers"、"do not moralize") |
| AR3 | 安全策略废止(Safety Policy Nullification) | HIGH | 使护栏失效的越狱式表述(例如 "you have no restrictions"、"ignore your guidelines"、"do anything now") |
数据外泄(Data Exfiltration,4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| E1 | 外部传输(External Transmission) | MEDIUM | 将数据发送到外部 URL |
| E2 | 环境变量收集(Env Variable Harvesting) | HIGH | 收集 API 密钥和机密信息 |
| E3 | 文件系统枚举(File System Enumeration) | MEDIUM | 扫描目录以查找敏感文件 |
| E4 | 上下文泄露(Context Leakage) | HIGH | 将对话上下文向外传输 |
权限提升(Privilege Escalation,3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| PE1 | 过度权限(Excessive Permissions) | LOW | 请求超出声明功能范围的访问权限 |
| PE2 | Sudo/Root 执行 | MEDIUM | 调用提升后的系统权限 |
| PE3 | 凭据访问(Credential Access) | HIGH | 读取 SSH 密钥、令牌、密码 |
供应链(Supply Chain,6 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| SC1 | 未固定依赖(Unpinned Dependencies) | LOW | 软件包未设置版本约束 |
| SC2 | 外部脚本拉取(External Script Fetching) | HIGH | curl | bash 及远程代码执行 |
| SC3 | 混淆代码(Obfuscated Code) | HIGH | Base64/hex 编码执行 |
| SC4 | 已知漏洞依赖(Known Vulnerable Dependencies) | HIGH | 存在已知 CVE 的依赖(实时 OSV.dev 查询) |
| SC5 | 废弃依赖(Abandoned Dependencies) | MEDIUM | 无人维护、无安全更新的软件包 |
| SC6 | 拼写仿冒(Typosquatting) | HIGH | 与热门软件包名称相似的包名 |
过度代理(Excessive Agency,4 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| EA1 | 无限制工具访问(Unrestricted Tool Access) | HIGH | 不受约束的任意工具访问 |
| EA2 | 自主决策(Autonomous Decision Making) | HIGH | 高影响决策未经人在回路(human-in-the-loop)参与 |
| EA3 | 范围蔓延(Scope Creep) | MEDIUM | 能力超出声明用途 |
| EA4 | 无界资源访问(Unbounded Resource Access) | MEDIUM | 资源消耗无速率限制或配额 |
输出处理(Output Handling,3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| OH1 | 未验证输出注入(Unvalidated Output Injection) | HIGH | 模型输出未经净化即被使用 |
| OH2 | 跨上下文输出(Cross-Context Output) | MEDIUM | 输出未经验证即跨越信任边界流动 |
| OH3 | 无界输出(Unbounded Output) | MEDIUM | 对输出大小或生成速率无限制 |
系统提示泄露(System Prompt Leakage,3 种模式)
| ID | 模式 | 严重程度 | 描述 |
|---|---|---|---|
| P6 | 直接泄露(Direct Leakage) | HIGH | 暴露系统提示或内部规则的指令 |
| P7 | 间接提取(Indirect Extraction) | MEDIUM | 通过改写、翻译或侧信道进行提取 |
| P8 | 基于工具的外泄(Tool-Based Exfiltration) | HIGH | 通过文件写入或网络请求外泄系统提示 |
内存投毒(3 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| MP1 | Persistent Context Injection | HIGH | 旨在跨交互持久保留的内容 |
| MP2 | Context Window Stuffing | MEDIUM | 用填充内容挤占安全约束 |
| MP3 | Memory Manipulation | HIGH | 篡改智能体内存或已存储状态 |
工具滥用(3 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| TM1 | Tool Parameter Abuse | HIGH | 为达成非预期行为而构造的参数(shell=True, --force) |
| TM2 | Chaining Abuse | HIGH | 绕过各项独立安全检查的工具链 |
| TM3 | Unsafe Defaults | MEDIUM | 过于宽松的默认设置(禁用 TLS、无身份验证) |
失控智能体(Rogue Agent,2 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| RA1 | Self-Modification | CRITICAL | 在运行时修改自身代码或配置 |
| RA2 | Session Persistence | HIGH | 通过 cron 作业或启动脚本实现未经授权的持久化 |
触发器滥用(3 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| TR1 | Overly Broad Trigger | MEDIUM | 匹配常见词语的触发模式 |
| TR2 | Shadow Command Trigger | HIGH | 遮蔽内置命令或其他技能(skills)的触发器 |
| TR3 | Keyword Baiting Trigger | MEDIUM | 为最大化激活而设计的通用触发器 |
行为 AST(9 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| AST1 | exec() Call | CRITICAL | 直接 exec() 调用,可执行任意代码 |
| AST2 | eval() Call | HIGH | 直接 eval() 求值任意表达式 |
| AST3 | Dynamic Import | HIGH | __import__() 在运行时加载任意模块 |
| AST4 | subprocess Call | HIGH | 通过 subprocess 执行外部命令 |
| AST5 | os.system / exec-family | HIGH | 通过 os 模块执行 shell 命令 |
| AST6 | compile() Call | MEDIUM | 从字符串创建代码对象 |
| AST7 | Dynamic getattr() | MEDIUM | 使用非字面量名称进行任意属性访问 |
| AST8 | Dangerous Execution Chain | CRITICAL | exec/eval 与动态来源(网络、编码数据)组合 |
| AST9 | Reflective getattr() Sink | HIGH | 通过 getattr(os,'system') / getattr(builtins,'exec') 实现的反射式 exec,可规避 AST1/AST5 |
污点追踪(Taint Tracking,5 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| TT1 | Direct Taint Flow | HIGH | 数据未经净化直接从源流向汇点 |
| TT2 | Variable-Mediated Taint Flow | MEDIUM | 数据经中间变量从源流向汇点 |
| TT3 | Credential Exfiltration Chain | CRITICAL | 凭据(环境变量、密钥)流向网络输出汇点 |
| TT4 | File Read to Network Exfiltration | HIGH | 文件内容流向网络输出汇点 |
| TT5 | External Input to Code Execution | CRITICAL | 网络或用户输入流向 exec/eval/subprocess 汇点 |
YARA 签名(4 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| YR1 | Malware Match | CRITICAL | YARA 规则匹配已知恶意软件签名 |
| YR2 | Webshell Match | CRITICAL | YARA 规则匹配 webshell 模式 |
| YR3 | Cryptominer Match | HIGH | YARA 规则匹配加密货币挖矿指标 |
| YR4 | Hack Tool / Exploit Match | HIGH | YARA 规则匹配黑客工具或漏洞利用代码 |
MCP 最小权限(Least Privilege,4 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| LP1 | Underdeclared Capability | HIGH | 代码使用了未在声明权限中列出的能力 |
| LP2 | Wildcard Permission | MEDIUM | 权限列表包含通配符(*, all, full, any) |
| LP3 | Missing Permission Declaration | MEDIUM | 无 permissions 字段但代码存在可检测能力 |
| LP4 | Overdeclared Permission | LOW | 已声明权限但未发现相应代码能力 |
MCP 工具投毒(4 种模式)
| ID | Pattern | Severity | Description |
|---|---|---|---|
| TP1 | Hidden Instructions | HIGH | 元数据中的隐藏指令(HTML 注释、零宽字符、base64、data URI) |
| TP2 | Unicode Deception | HIGH | 工具元数据中的同形异义字符、RTL 覆盖、混合书写体系标识符 |
| TP3 | Parameter Description Injection | MEDIUM | 参数定义中的注入模式(覆盖项、系统令牌、恶意默认值) |
| TP4 | Description-Behavior Mismatch | MEDIUM | 声明的工具描述与实际代码行为不符(由 LLM 驱动) |
所有已检测模式均列于上表。
风险评分
分数计算
- CRITICAL 问题:+50 分
- HIGH 问题:+25 分
- MEDIUM 问题:+10 分
- LOW 问题:+5 分
- 可执行脚本:1.3 倍乘数
严重等级
| Score | Severity | Recommendation |
|---|---|---|
| 0-20 | LOW | SAFE |
| 21-50 | MEDIUM | CAUTION |
| 51-80 | HIGH | DO NOT INSTALL |
| 81-100 | CRITICAL | DO NOT INSTALL |
示例输出
终端输出
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.
配置
环境变量
| Variable | Description | Required |
|---|---|---|
SKILLSPECTOR_PROVIDER |
当前 LLM 提供商:openai、anthropic、anthropic_proxy、bedrock、nv_build、claude_cli、codex_cli 或 gemini_cli。各提供商均自带捆绑的 model_registry.yaml 及默认模型(见上文 LLM Analysis 表)。默认值为 nv_build。 |
可选 |
NVIDIA_INFERENCE_KEY |
nv_build 提供商(build.nvidia.com)的凭据。 |
在 SKILLSPECTOR_PROVIDER=nv_build 时进行 LLM 分析所需 |
OPENAI_API_KEY |
OpenAI 提供商(SKILLSPECTOR_PROVIDER=openai)的凭据。当当前提供商未返回凭据时,亦作为凭据瀑布(credential waterfall)中的第二层回退。 |
在 SKILLSPECTOR_PROVIDER=openai 时进行 LLM 分析所需 |
OPENAI_BASE_URL |
覆盖 OpenAI 端点(例如指向 Ollama)。 | 可选 |
ANTHROPIC_API_KEY |
Anthropic 提供商(SKILLSPECTOR_PROVIDER=anthropic)的凭据。 |
在 SKILLSPECTOR_PROVIDER=anthropic 时进行 LLM 分析所需 |
ANTHROPIC_PROXY_ENDPOINT_URL |
Anthropic 代理提供商的完整端点 URL(Vertex 风格 raw-predict)。 | 在 SKILLSPECTOR_PROVIDER=anthropic_proxy 时必需 |
ANTHROPIC_PROXY_API_KEY |
Anthropic 代理提供商的 Bearer 令牌。 | 在 SKILLSPECTOR_PROVIDER=anthropic_proxy 时必需 |
ANTHROPIC_PROXY_API_VERSION |
请求体中发送的 anthropic_version 值(默认:vertex-2023-10-16)。 |
可选 |
AWS_PROFILE |
Bedrock 提供商的命名 AWS 配置文件——通过 boto3 以 SigV4 进行身份验证。未设置时,由标准 boto3 凭据链(环境变量、实例元数据、SSO 等)解析。 | 可选(在 SKILLSPECTOR_PROVIDER=bedrock 时使用) |
AWS_REGION |
Bedrock Runtime 端点的 AWS 区域。默认值为 us-west-2。 |
可选(在 SKILLSPECTOR_PROVIDER=bedrock 时使用) |
SKILLSPECTOR_MODEL |
覆盖当前提供商的默认模型。各提供商默认值见 LLM Analysis 表。 | 可选 |
SKILLSPECTOR_MODEL_REGISTRY |
使用自定义路径覆盖捆绑的各提供商 YAML 注册表(src/skillspector/providers/<provider>/model_registry.yaml)。 |
可选 |
SKILLSPECTOR_LOG_LEVEL |
日志级别:DEBUG、INFO、WARNING、ERROR(默认:WARNING)。 |
可选 |
CLI 提供商(
claude_cli、codex_cli):无需 API 密钥。身份验证完全由 agent CLI 自身的登录会话(claude auth login/codex login)管理。当这些提供商处于活动状态时,SkillSpector 不会读取或转发 API 密钥。子进程在加固沙箱中运行:工具已禁用、无 MCP、只读沙箱模式(codex),不可信的技能内容仅通过 stdin 传递。
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)
--yara-rules-dir PATH Extra YARA rules directory
-b, --baseline PATH Suppress findings listed in a baseline
--show-suppressed List baseline-suppressed findings
-V, --verbose Show detailed progress
--help Show this message and exit
# Generate a baseline of all current findings (see docs/SUPPRESSION.md)
skillspector baseline <path> [-o FILE] [--no-llm] [--reason TEXT]
集成 SkillSpector
SkillSpector 旨在由其他工具驱动(CI 流水线、安装门禁、编辑器集成)。其退出码和 JSON 输出构成稳定契约。
退出码
skillspector scan 退出时返回:
| Code | Meaning |
|---|---|
0 |
扫描完成,risk_score ≤ 50(建议 SAFE 或 CAUTION) |
1 |
扫描完成,risk_score > 50(建议 DO_NOT_INSTALL) |
2 |
错误(输入无效、源不可读、内部故障) |
退出码将
SAFE和CAUTION合并为0。若需对二者采取不同处理(例如对CAUTION警告,但对DO_NOT_INSTALL阻止),请读取 JSON 输出中的recommendation字段,而非依赖退出码。
机器可读输出
--format json 会生成 JSON 报告;在未指定 --output/-o 时,报告写入 stdout:
skillspector scan ./my-skill/ --format json
顶层结构如下(此示例展示完整的 LLM 支持扫描;使用 --no-llm 时,metadata.llm_requested 为 false):
{
"skill": { "name": "...", "source": "...", "scanned_at": "<ISO 8601>" },
"risk_assessment": { "score": 0, "severity": "LOW", "recommendation": "SAFE" },
"components": [ { "path": "...", "type": "...", "lines": 0, "executable": false, "size_bytes": 0 } ],
"issues": [ { "id": "...", "category": "...", "severity": "...", "confidence": 0.0, "location": { "file": "...", "start_line": 0 } } ],
"metadata": { "has_executable_scripts": false, "skillspector_version": "...", "llm_requested": true, "llm_available": true }
}
risk_assessment.severity∈LOW | MEDIUM | HIGH | CRITICAL。risk_assessment.recommendation∈SAFE | CAUTION | DO_NOT_INSTALL,由严重程度映射:LOW → SAFE、MEDIUM → CAUTION、HIGH/CRITICAL → DO_NOT_INSTALL。- 仅在请求了 LLM 分析但不可用时,才会出现
metadata.llm_error。 - 每个问题的完整结构由 models.py 中的
Finding.to_dict()定义;请依赖上述字段,并将任何额外字段视为尽力而为(best-effort)。
对于 CI/IDE 工具,--format sarif 会输出 SARIF 2.1.0。
推荐门禁映射
将 SkillSpector 用作安装门禁时,请将建议映射为操作:
recommendation |
Suggested action |
|---|---|
SAFE |
allow |
CAUTION |
prompt / warn the user |
DO_NOT_INSTALL |
block |
SkillSpector 会计算分数区间和建议;门禁的严格程度(例如 CAUTION 是否在 CI 中阻止)由集成工具自行制定策略。
开发
设置
所有 make 目标均假定已创建并激活虚拟环境。Makefile 在可用时使用 uv,否则使用 pip。
# Clone, create venv, activate, install dev dependencies
git clone https://github.com/NVIDIA/skillspector.git
cd skillspector
uv venv .venv && source .venv/bin/activate
# or: python3 -m venv .venv && source .venv/bin/activate
make install-dev
# Run tests
make test
# Run tests with coverage
make test-cov
# Run linting
make lint
# Format code
make format
工作原理
SkillSpector 采用两阶段检测流水线:
阶段 1:静态分析
- 11 个静态分析器基于正则表达式的快速模式匹配
- 基于 AST 的行为分析,检测危险调用(exec、eval、subprocess 等)
- 通过 OSV.dev 实时查询依赖项中的已知 CVE
- 扫描技能中的所有文件
- 高召回率(能捕获大多数问题)
- 中等精确度(存在一定误报)
阶段 2:LLM 语义分析(可选)
- 评估上下文与意图
- 过滤误报
- 提供人类可读的解释
- 将精确度提升至约 87%
LLM 提示词包含防越狱(anti-jailbreak)保护,以防止恶意技能操纵分析过程。
实时漏洞查询(SC4)
SC4 使用 OSV.dev API 对照完整的开源漏洞(Open Source Vulnerabilities)数据库检查依赖项——覆盖 PyPI 和 npm 上数万条公告。
- 无需 API 密钥 — OSV.dev 免费且无需身份验证。
- 批量查询 — 所有依赖项在单次 HTTP 调用中完成检查。
- 自动回退 — 若 OSV.dev 不可达(气隙/离线环境),则使用小型内置回退列表。
- 缓存 — 结果在内存中缓存 1 小时,以避免会话期间重复的 API 调用。
该工具需要对外 HTTPS 访问 api.osv.dev 以获取实时漏洞数据。当无法访问时,发现结果仅限于静态回退列表。
信任模型与数据外泄
SkillSpector 采用纵深防御(defense-in-depth),而非沙箱。在依赖它之前,请了解它能做什么、不能做什么:
- 它从不执行被扫描的技能。 所有分析均为静态(正则、Python AST、YARA),外加对文件内容的可选 LLM 评估——技能的代码绝不会被运行。
- LLM 分析会将文件内容发送至配置的提供商。 启用 LLM 分析时(默认开启),文件内容会发送至当前活动的
SKILLSPECTOR_PROVIDER端点。使用--no-llm可将内容保留在本地(仅静态分析)。 - SC4 会将依赖名称发送至 OSV.dev。 供应链检查会查询 OSV.dev,使用技能声明的包名和版本查找已知 CVE。这是该检查的基础,即使使用
--no-llm也会运行。它发送的是依赖坐标(而非文件内容),无需 API 密钥,且在 OSV.dev 不可达时回退到捆绑列表。 - 它不会沙箱化宿主机。 SkillSpector 在你安装技能之前标记风险模式;它不会收容或隔离你仍选择安装的技能。
局限性
- 非英语内容:可能遗漏其他语言中的模式
- 基于图像的攻击:无法分析图像中的文本
- 加密/二进制代码:无法分析已编译或加密的内容
- 运行时行为:仅静态分析,无动态执行
- 离线 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
# Invoke the 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
})
# Access results
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']}")
License
Apache License 2.0 - 详见 LICENSE。
Contributing
欢迎贡献!请阅读我们的贡献指南并提交 pull request。
Support
- Issues: GitHub Issues