
将静态分析能力以 MCP 协议接入 AI Agent,实现开发环境内的实时安全审计。
一、问题背景
SAST(静态应用安全测试)是 DevSecOps 的关键环节,但现有工具体验存在几个痛点:
- 流程割裂:写代码 → Push → CI 触发 → 扫描 → 生成报告 → 登录平台查看 → 定位修复,多个工具来回切换
- 配置复杂:SonarQube、Checkmarx 等商业工具需要独立部署、配置规则集、维护数据库
- 成本高:商业许可费用数千至数十万/年,个人开发者和小团队难以承受
- 误报率高:大量误报需要人工过滤,削弱了工具的实用性
ai-agent-scan 通过 MCP 协议将 SAST 能力直接注入 AI 编程助手的对话上下文,让安全审计变成聊天框里的一条指令。
二、MCP 协议集成架构
2.1 什么是 MCP
MCP(Model Context Protocol)是 Anthropic 开源的 AI 工具调用协议标准。它为 AI 客户端和外部工具定义了统一的通信契约------基于 JSON-RPC 2.0 的 tools/list 和 tools/call 两个核心方法。任何实现该协议的客户端(Claude Code、VS Code、Cursor 等)都能无差别调用兼容的工具。
2.2 通信流程
ai-agent-scan 作为 MCP Server,通过 stdio transport 与客户端通信:
vbscript
// Step 1: 客户端发现工具列表(tools/list)
Request → {"jsonrpc":"2.0","method":"tools/list","id":1}
Response ← {
"tools": [{
"name": "scan_sast",
"description": "SAST 安全扫描,检测 SQL 注入、XSS、SSRF 等",
"inputSchema": { "path": "string", "language": "string?" }
}, {
"name": "check_secrets",
"description": "扫描硬编码密钥和凭证",
...
}, {
"name": "audit_deps",
"description": "依赖 CVE 漏洞审计",
...
}, {
"name": "scan_all",
"description": "全量安全扫描",
...
}]
}
// Step 2: 客户端调用工具(tools/call)
Request → {
"jsonrpc":"2.0","method":"tools/call","id":2,
"params": {
"name":"scan_sast",
"arguments":{"path":"/project/src","language":"javascript"}
}
}
Response ← {
"content": [{
"type": "text",
"text": "🔴 CRITICAL: SQL Injection @ user.js:25\n ...
🟡 MEDIUM: Stored XSS @ profile.js:18\n ..."
}]
}
MCP 服务器启动后保持进程常驻,每次 tools/call 执行对应的 handler 函数并返回结果。
三、扫描引擎技术实现
3.1 双引擎架构
引擎采用分层设计,上层 PatternAnalyzer 负责快速命中,下层 DataFlowAnalyzer 负责深度追踪。
PatternAnalyzer(模式匹配引擎)
逐行正则匹配已知的危险函数调用,规则以 JSON 文件定义:
json
{
"id": "SC-001",
"name": "Command Injection",
"severity": "critical",
"patterns": ["exec(", "spawn(", "shell_exec(", "subprocess.call("],
"message": "检测到命令注入风险,用户输入不可直接传递给系统命令执行函数",
"sink": "dangerous_call"
}
适用场景:检测 eval()、innerHTML 直接赋值、硬编码密钥等特征明显的模式。
DataFlowAnalyzer(数据流分析引擎)
基于 AST(抽象语法树)的源-汇(Source-Sink)污点传播分析。处理链路:
sql
用户输入(Source)
→ 变量赋值传播(Variable Propagation)
→ 跨函数传参(Cross-function Taint Flow)
→ 到达危险函数(Sink)
→ 输出漏洞报告
核心数据流追踪逻辑:
javascript
// 数据流分析主流程(简化伪代码)
function scanFile(ast) {
const sources = findSources(ast, [
'req.body', 'req.query', // Express.js
'request.form', // Python Flask
'getParameter', 'getQueryString' // Java Servlet
])
const sinks = findSinks(ast, [
'query', 'execute', // SQL
'innerHTML', 'document.write', // XSS
'exec', 'spawn', 'run', // Command
'open', 'request.get' // SSRF
])
return traceToSinks(ast, sources, sinks)
}
// 变量传播追踪
function traceToSinks(ast, sources, sinks) {
const taintMap = new Map()
// 标记初始污染源
for (const src of sources) {
taintMap.set(src.varName, { tainted: true, chain: [src] })
}
// 沿赋值链传播污点标记
for (const node of ast.body) {
if (node.type === 'VariableDeclaration') {
for (const decl of node.declarations) {
const rhs = resolveExpression(decl.init)
if (taintMap.has(rhs)) {
// 污染传播:a = tainted_b → a 也被标记
taintMap.set(decl.id.name, { ...taintMap.get(rhs) })
}
}
}
}
// 检测污染数据是否到达 sink
for (const sink of sinks) {
const argTaint = resolveArgTaint(sink.args, taintMap)
if (argTaint.tainted) {
return { vulnerability: sink.type, chain: argTaint.chain }
}
}
}
这种分析能发现跨越多层变量赋值的间接漏洞:
javascript
function processOrder(req, res) {
const raw = req.body.name // Source: 用户输入
const tmp = raw // 赋值传播
const name = sanitize(tmp) // sanitize 未定义,传播未中断
const sql = `SELECT * FROM users WHERE name = '${name}'`
db.query(sql) // Sink: SQL注入
}
3.2 跨语言支持
引擎核心由 JavaScript 编写,解析层使用 @babel/parser。对于非 JavaScript 语言(Python、Java、Go),使用 textBasedDataflowAnalyze 进行文本级分析------通过语言特定的正则规则识别 source/sink 模式,在不引入额外 parser 依赖的前提下实现跨语言覆盖。
| 语言 | 分析方式 | 覆盖规则 |
|---|---|---|
| JavaScript/TypeScript | AST 解析 + 数据流追踪 | SQL注入、XSS、命令注入、SSRF、路径遍历 |
| Python | 文本分析 | SQL注入、命令注入(cursor.execute, subprocess) |
| Java | 文本分析 | SQL注入、命令注入(executeQuery, Runtime.exec) |
| Go | 文本分析 | SQL注入、命令注入(db.Query, exec.Command) |
3.3 自描述模块系统
每个扫描工具是一个独立的 .js 文件,通过命名导出声明 MCP 接口契约:
javascript
// scripts/sast.js --- 完整自描述模块
export const name = 'scan_sast'
export const description = 'SAST 安全扫描'
export const schema = {
type: 'object',
properties: {
path: { type: 'string', description: '项目路径' },
language: { type: 'string', description: '限定语言' },
rules: { type: 'array', items: { type: 'string' }, description: '指定规则 ID' }
}
}
export async function handler(args) {
// 业务逻辑实现
return scanProject(args.path, { language: args.language, rules: args.rules })
}
MCP 服务器启动时自动扫描 scripts/ 目录,通过动态导入注册所有模块。新增工具只需创建新文件,零配置。
javascript
// mcp-server.js --- 自动注册所有工具
for (const file of readdirSync(scriptsDir).filter(f => f.endsWith('.js'))) {
const mod = await import(pathToFileURL(join(scriptsDir, file)))
if (mod.name && mod.handler) {
server.tool(mod.name, mod.description, toZodSchema(mod.schema), mod.handler)
}
}
四、性能对比
| 维度 | ai-agent-scan | 传统 SAST |
|---|---|---|
| 启动到出结果 | < 1 秒 | 3-15 分钟(需编译) |
| 配置步骤 | 0(自动注册) | 5-10 步 |
| 集成方式 | MCP 协议 | REST API / CLI / IDE 插件 |
| 规则管理 | JSON 文件,可扩展 | 专有规则语言 |
| 误报率 | 中,规则可调参 | 高,需人工筛选 |
| 语言覆盖 | JS/TS/Python/Java/Go | 通常单语言 |
| 许可 | MIT 开源 | 商业许可 |
传统 SAST 的延迟主要来自编译步骤:源码 → 编译 → IR 构建 → 分析。ai-agent-scan 直接解析源码 AST,绕过编译阶段,适合快速迭代和本地开发场景。
五、安装与使用
安装
bash
npm install -g ai-agent-scan
MCP 注册
Claude Code:
bash
claude mcp add ai-agent-scan -s user -- npx ai-agent-scan
VS Code / Cursor 等客户端在对应配置文件中添加 stdio 配置即可。
一键配置
bash
npx ai-agent-scan-setup
该命令自动部署 SKILL.md 到 ~/.claude/skills/ 并将 MCP 服务器配置写入 ~/.claude.json。
使用示例
在 AI 聊天框中输入:
帮我扫描这个项目的安全漏洞
/path/to/project
或者直接在终端使用:
bash
npx ai-agent-scan
MCP 客户端会自动发现 scan_sast、check_secrets、audit_deps、scan_all 四个工具。
六、Roadmap
- Rules Marketplace --- 社区贡献规则的开箱即用仓库
- 自动修复(AutoFix) --- 基于漏洞类型和代码上下文生成修复 diff
- CI/CD 集成 --- GitHub Actions、GitLab CI 官方 Action
- 自定义规则 DSL --- 声明式规则编写,无需修改引擎代码
- 增量扫描 --- 仅扫描变更文件,提升大型项目效率
- SARIF 导出 --- 兼容 GitHub Security Tab、VS Code 问题面板
七、开源信息
- 仓库:github.com/peterfei/ai...
- 许可:MIT
- npm:www.npmjs.com/package/ai-...
贡献方式:提交 PR、编写规则、报告 bug。
v1.0.0 已发布。支持 SAST 检测 / 密钥扫描 / 依赖 CVE 审计 / 全量扫描,覆盖 JavaScript、TypeScript、Python、Java、Go 语言。