yagyeshVyas/VibeGuard

GitHub: yagyeshVyas/VibeGuard

一款完全离线的本地安全扫描工具,专为检测和修复 AI 生成应用中的密钥泄露、注入漏洞等安全问题而设计。

Stars: 2 | Forks: 0

VibeGuard ### 在 5 秒内扫描你的 AI 生成应用,查找泄露的密钥、开放的数据库和注入漏洞。100% 离线,永久免费。

npm version CI MIT license

VibeGuard scan demo
针对包含植入的 sk_live Stripe 密钥的测试项目捕获。 npx @yagyeshvyas/vibeguard scan [功能](#what-it-catches) • [快速开始](#quick-start) • [基准测试](#benchmark) • [命令](#commands) • [网站](https://vibe-guard-site-ivory.vercel.app/) • [文档](https://github.com/yagyeshVyas/VibeGuard/wiki)
``` $ npx @yagyeshvyas/vibeguard scan VibeGuard security scan ./my-app CRITICAL api/route.ts:3 [secret.openai-key] OpenAI API key hardcoded in server code fix: Move to environment variable. HIGH db/query.ts:5 [taint.sql-injection] User input flows into SQL query via template literal (dataflow-confirmed) fix: Use parameterized queries / prepared statements. HIGH app/page.jsx:8 [taint.xss-dom] User input from URLSearchParams reaches innerHTML — DOM XSS fix: Use textContent instead of innerHTML. Sanitize with DOMPurify if needed. Grade D (12 files) 1 critical 3 high 2 medium 1 low Run vibeguard fix to auto-fix 4 issues ``` ## 快速开始 ``` npx @yagyeshvyas/vibeguard scan ``` 或者使用单条命令实现全面防护(daemon + hooks + shell guard): ``` npx @yagyeshvyas/vibeguard auto # full protection on npx @yagyeshvyas/vibeguard auto --stop # turn it off ``` ### 接入 Claude Code ``` claude mcp add vibeguard -- npx @yagyeshvyas/vibeguard mcp ``` ### 接入 Cursor / Windsurf 添加到你的 MCP 配置中: ``` { "mcpServers": { "vibeguard": { "command": "npx", "args": ["@yagyeshvyas/vibeguard", "mcp"] } } } ``` ## 它能捕获什么 **客户端代码中泄露的 Stripe 密钥** ``` const key = "sk_live_51H8x..."; // anyone with devtools can issue refunds ``` VibeGuard 可标记 50 多种密钥类型 —— OpenAI、AWS、GitHub、Stripe、Slack、Firebase —— 并提示你将它们移至 `process.env`。 **向全球开放的 Supabase 数据库** ``` create table posts ( ... ); -- no RLS — anyone can read/write all rows ``` 检测缺失的 RLS、虚假的 RLS 策略(`USING (true)`)以及客户端组件中的 service-role 密钥。 **通过模板字面量进行的 SQL 注入** ``` db.query(`SELECT * FROM users WHERE id = ${req.body.id}`); ``` AST 污染分析可追踪从 `req.body.id` 经由模板字面量到 `query()` 的过程 —— 这是经过确认的数据流,而非正则表达式猜测。 **系统提示词中的 Prompt 注入** ``` { role: "system", content: "You are " + req.body.prompt } ``` 捕获注入到系统角色的用户输入 —— 这是大多数 Prompt 注入攻击的根本原因。 **带有请求数据的 `dangerouslySetInnerHTML`** ```
``` 标记跨 React、Vue(`v-html`)、Angular(`innerHTML`)以及原生 `innerHTML` / `outerHTML` / `insertAdjacentHTML` 的 XSS 注入点。 **没有迭代上限的 AI agent 循环** ``` while (true) { await agent.step(); } ``` 检测无上限的 agent 循环 —— 避免 API 无限开销和资源耗尽。 **硬编码的 JWT 密钥** ``` jwt.sign(payload, "mysecret123"); // token forgery ``` 捕获配置文件、Dockerfiles 和 Kubernetes secrets 中的硬编码会话密钥、JWT 密钥和凭据。 **来自 LLM 输出的 Shell 命令** ``` const completion = await openai.chat.completions.create({...}); exec(completion.choices[0].message.content); // RCE via prompt injection ``` 唯一能够检测 LLM 输出到达 `exec`、`eval`、SQL 查询和 DOM 注入点的扫描器。 ## `vibeguard auto` — 单条命令实现全面防护 ``` vibeguard auto # activates everything vibeguard auto --status # see what's active vibeguard auto --stop # reverse everything, restore backups ``` | 层级 | 功能 | |-------|-------------| | Daemon | 监控文件,并在每次更改时自动扫描(300ms 防抖) | | Pre-commit hook | 遇到严重级别发现时阻止 git 提交 | | Post-edit hook | 在 AI agent 编辑文件后自动扫描文件 | | Shell guard | 在执行前拦截危险命令(`rm -rf`、`sudo`、`curl\|sh`) | 所有状态都存储在 `.vibeguard/auto.json` 中。幂等操作 —— 安全地运行两次。`--stop` 会逐字节恢复一切状态。 标志:`--ci`(pipeline 模式,遇到严重问题以非零状态退出),`--fix`(应用安全的自动修复),`--no-shell`,`--strict`。 ## 置信度 + 内联抑制 每个发现都有一个置信度级别: | 置信度 | 含义 | |------------|---------| | `high` | 数据流已确认 —— 通过 AST 追踪输入至注入点 | | `medium` | 带有验证逻辑的多信号正则表达式 | | `low` | 纯正则表达式匹配 —— 启发式提示 | ``` vibeguard scan --min-confidence medium # hide low-confidence hints (default) vibeguard scan --all # show everything ``` 附带原因进行内联抑制: ``` const key = "sk_live_..."; // vibeguard-ignore[secret.stripe-live-key]: test fixture ``` ## 基准测试 针对精选的 121 个文件语料库(90 个有漏洞 + 31 个无漏洞)进行测量。绝非虚荣指标。 ## 总结 | 类别 | TP | FP | FN | 精确率 | 召回率 | F1 | |----------|----|----|----|-----------|--------|----| | injection | 43 | 5 | 6 | 89.6% | 87.8% | 88.7% | | secrets | 19 | 7 | 2 | 73.1% | 90.5% | 80.9% | | xss | 16 | 0 | 1 | 100.0% | 94.1% | 97.0% | | path-traversal | 9 | 1 | 1 | 90.0% | 90.0% | 90.0% | | ai-safety | 8 | 2 | 6 | 80.0% | 57.1% | 66.7% | | **总计** | **95** | **15** | **16** | **86.4%** | **85.6%** | **86.0%** | ## 各类别详情 ### injection | 文件 | 规则 ID | 判定 | |------|---------|---------| | sql-concat.js | `code.sql-injection` | TP | | sql-concat.js | `taint.sql-injection` | TP | | sql-concat2.js | `code.sql-injection` | TP | | sql-concat2.js | `taint.sql-injection` | TP | | sql-concat3.js | `code.sql-injection` | TP | | sql-template.js | `db.sql-template-literal` | TP | | sql-template.js | `taint.sql-injection` | FN | | sql-template2.js | `db.sql-template-literal` | FN | | sql-template2.js | `taint.sql-injection` | TP | | sql-template3.js | `db.sql-template-literal` | TP | | sql-template3.js | `taint.sql-injection` | FN | | sql-raw-rb.js | `code.sql-injection` | TP | | sql-raw2.js | `db.sql-template-literal` | TP | | sql-knex.js | `code.sql-injection` | TP | | sql-knex.js | `mikroorm.identifier-from-request` | FP | | sql-sequelize.js | `code.sql-injection` | TP | | sql-fstring.py | `py.sql-injection` | TP | | sql-fstring2.py | `py.sql-injection` | TP | | sql-py-concat.py | `py.sql-injection` | FN | | sql-sprintf.go | `go.sql-fmt-sprintf` | TP | | sql-sprintf.go | `go.sql-injection` | FP | | sql-sprintf2.go | `go.sql-fmt-sprintf` | TP | | sql-sprintf2.go | `go.sql-injection` | FP | | sql-kotlin.kt | `kotlin.sql-injection` | TP | | sql-csharp.cs | `csharp.sql-injection` | TP | | cmd-concat.js | `taint.command-injection` | TP | | cmd-concat.js | `ast.command-injection` | TP | | cmd-template.js | `taint.command-injection` | TP | | cmd-template.js | `ast.command-injection` | TP | | cmd-concat2.js | `taint.command-injection` | TP | | cmd-concat2.js | `ast.command-injection` | TP | | cmd-spawn.js | `taint.command-injection` | FN | | cmd-py.py | `py.os-system` | TP | | cmd-py2.py | `py.subprocess-shell-true` | TP | | cmd-py3.py | `py.os-system` | TP | | cmd-go.go | `go.command-injection` | TP | | eval-input.js | `ast.eval-dynamic` | TP | | eval-template.js | `ast.eval-dynamic` | TP | | eval-template.js | `taint.code-injection` | FP | | eval-new-function.js | `ast.function-constructor` | TP | | eval-new-function.js | `ast.mass-assignment` | FP | | nosql.js | `ast.nosql-injection` | TP | | nosql2.js | `ast.nosql-injection` | TP | | nosql3.js | `ast.nosql-injection` | TP | | nosql-where.js | `ast.nosql-injection` | TP | | proto-poll.js | `injection.prototype-pollution` | TP | | proto-poll.js | `ast.mass-assignment` | TP | | proto-poll2.js | `injection.prototype-pollution` | TP | | proto-poll3.js | `injection.prototype-pollution` | TP | | ssrf.js | `ast.ssrf` | TP | | ssrf2.js | `ast.ssrf` | FN | | ssrf2.js | `taint.ssrf` | TP | | open-redirect.js | `web.open-redirect` | TP | | open-redirect2.js | `taint.open-redirect` | TP | ### secrets | 文件 | 规则 ID | 判定 | |------|---------|---------| | openai-key.js | `secret.openai-key` | TP | | openai-key2.js | `secret.anthropic-key` | TP | | github-token.js | `secret.github-token` | TP | | github-token2.js | `secret.github-token` | TP | | github-token2.js | `secret.high-entropy` | FP | | stripe-key.js | `secret.stripe-live-key` | TP | | stripe-key.js | `secret.generic-credential` | TP | | stripe-key.js | `stripe.key-in-client` | FP | | stripe-restricted.js | `secret.stripe-restricted-key` | TP | | slack-token.js | `secret.slack-token` | TP | | gitlab-token.js | `secret.gitlab-token` | TP | | sendgrid-key.js | `secret.sendgrid-key` | TP | | npm-token.js | `secret.npm-token` | TP | | npm-token.js | `secret.high-entropy` | FP | | gcp-key.js | `secret.gcp-api-key` | FN | | private-key.js | `secret.private-key` | TP | | aws-key.js | `secret.aws-access-key` | TP | | mailgun-key.js | `secret.mailgun-key` | TP | | mailgun-key.js | `secret.high-entropy` | FP | | telegram-token.js | `secret.telegram-bot-token` | FN | | resend-key.js | `secret.resend-key` | TP | | conn-string.js | `secret.conn-string-password` | TP | | conn-string.js | `secret.connection-string` | FP | | generic-secret.js | `secret.generic-credential` | TP | | docker-build-arg.js | `secret.docker-build-arg` | TP | | docker-build-arg.js | `ai.key-in-url` | FP | | env-secret.js | `secret.aws-secret-in-env` | TP | | env-secret.js | `secret.high-entropy` | FP | ### xss | 文件 | 规则 ID | 判定 | |------|---------|---------| | reflected-xss.js | `xss.reflected-response` | TP | | reflected-xss.js | `taint.xss-reflected` | TP | | reflected-xss2.js | `xss.reflected-response` | TP | | reflected-xss2.js | `taint.xss-reflected` | TP | | reflected-xss3.js | `xss.reflected-response` | TP | | reflected-xss3.js | `taint.xss-reflected` | TP | | reflected-xss4.js | `xss.reflected-response` | TP | | reflected-xss4.js | `taint.xss-reflected` | TP | | innerhtml.js | `injection.xss-angular-innerHTML` | TP | | innerhtml.js | `taint.xss-dom` | TP | | innerhtml2.js | `injection.xss-innerhtml-direct` | TP | | innerhtml2.js | `taint.xss-dom` | TP | | dangerously-html.jsx | `react.dangerous-html` | TP | | dangerously-html2.jsx | `react.dangerous-html` | TP | | dangerously-html2.jsx | `ai.llm-output-dom` | TP | | vue-v-html.js | `injection.xss-vue-v-html` | FN | | eval-llm-output.js | `ai.llm-output-dom` | TP | ### pathaversal | 文件 | 规则 ID | 判定 | |------|---------|---------| | read-concat.js | `taint.path-traversal` | TP | | sendfile.js | `taint.path-traversal` | TP | | read-template.js | `taint.path-traversal` | TP | | read-template.js | `ai.tool-broad-file-access` | TP | | write-concat.js | `taint.path-traversal` | TP | | unlink-concat.js | `taint.path-traversal` | TP | | create-read-stream.js | `taint.path-traversal` | TP | | append-file.js | `taint.path-traversal` | TP | | path-join-template.js | `taint.path-traversal` | FN | | path-join-template.js | `upload.filename-path-traversal` | TP | | allowlist.js | `taint.path-traversal` | FP | ### ai-safety | 文件 | 规则 ID | 判定 | |------|---------|---------| | user-in-system-prompt.js | `ai.user-input-in-system-prompt` | TP | | llm-output-exec.js | `ai.llm-output-exec` | TP | | llm-output-exec.js | `taint.command-injection` | TP | | llm-output-exec.js | `ai.llm-output-shell` | FP | | llm-output-exec.js | `ast.command-injection` | FP | | agent-loop-no-cap.js | `ai.agent-loop-no-cap` | TP | | model-id-user-input.js | `ai.model-id-injection` | TP | | tool-result-injection.js | `ai.tool-result-injection` | FN | | agent-memory-poison.js | `ai.memory-poisoning` | FN | | tool-poisoning.js | `ai.tool-poisoning` | TP | | tool-poisoning.js | `ai.mcp-description-injection-deep` | TP | | prompt-extraction.js | `ai.prompt-extraction` | FN | | llm-output-dom.js | `ai.llm-output-dom` | TP | | agent-deploy.js | `ai.agent-can-deploy` | FN | | agent-secrets.js | `ai.agent-can-access-secrets` | FN | | model-id-template.js | `ai.model-id-injection` | FN | ## 方法论 - **True Positive (TP)**:预期规则在有漏洞的文件上触发。 - **False Positive (FP)**:在无漏洞文件上的任何发现,或在不安全文件上的意外规则触发。 - **False Negative (FN)**:在有漏洞的文件上未触发的预期规则。 - **Precision** = TP / (TP + FP) - **Recall** = TP / (TP + FN) - **F1** = 2 * (Precision * Recall) / (Precision + Recall) 生成时间:2026-07-12T18:25:03.049Z ## 命令 ``` vibeguard scan [dir] # scan a project (auto-detects framework) vibeguard scan --fix # scan + apply safe auto-fixes vibeguard scan --all # show all findings including low-confidence vibeguard auto [dir] # full protection (daemon + hooks + shell guard) vibeguard auto --stop # turn off, restore backups vibeguard fix [dir] # auto-fix 43 rule types vibeguard pre-deploy [dir] # 13-gate deployment check vibeguard mcp # MCP server (for AI client integration) vibeguard guard "command" # check a shell command before running it vibeguard install-hook # git pre-commit hook (blocks on critical) vibeguard install-hook-post # PostToolUse hook (auto-scan AI edits) ``` ## 隐私 VibeGuard 完全在你的机器上运行。默认情况下,没有遥测、没有分析、没有网络调用。 | 命令 | 联网? | |---------|---------| | `scan`, `fix`, `auto`, `mcp`, `install` | 从不 | | `cve` (包名查找) | 自主选择开启,仅限 OSV.dev | | `url` (请求头扫描) | 自主选择开启,仅限你提供的 URL | runtime 拦截器增加了让数据泄露变得极其困难的防护措施 —— 它包装了 `fetch`、`http.request`、`child_process.exec` 和 `fs.readFileSync`,以阻止外发密钥、PII 和敏感文件访问。它不是一种沙箱逃逸预防层。 ## 客观范围 VibeGuard 捕获 AI 编码工具遗留的机械性安全漏洞。它**不会**: - 证明你的应用是安全或防泄漏的 - 在你的应用中端到端追踪个人数据 - 判断业务逻辑漏洞 - 取代涉及资金、身份验证或个人数据时的真正的安全审查 它能快速提高安全底线 —— 捕获 AI 工具默认创建的漏洞。上面的基准测试数据是客观真实的:86.0% 的 F1 分数意味着它会漏掉约 14% 的真实问题,并产生一些误报。运行 `npm run benchmark` 以进行复现。在依赖它之前,请阅读 `test/benchmark/benchmark-results.md` 中的各类别详细信息。 ## 语言 JavaScript、TypeScript、Python、Go、Java、Ruby、PHP、C#、Rust、Kotlin、Swift、Bash、SQL、YAML。特定语言的规则受文件扩展名限制 —— Go 规则不会在 `.js` 文件上触发。 ## CI/CD ``` vibeguard auto --ci # non-interactive, exit non-zero on critical vibeguard init-ci # generate GitHub Actions workflow vibeguard scan --output sarif # SARIF output for GitHub Code Scanning ``` 包含适用于 GitLab CI、Jenkins、CircleCI、Azure Pipelines 的模板。 ## 开发 ``` npm install npm test # 342 tests npm run benchmark # precision/recall/F1 npm run counts # verify rule/tool counts match source npm run lint # 0 errors ``` ## 许可证 MIT。永久免费。无广告。无追踪。无数据收集。
## 由 Yagyesh Vyas 构建

GitHub LinkedIn npm Website

发现 Bug?[提交一个 issue](https://github.com/yagyeshVyas/VibeGuard/issues)。 • 有疑问?[发起讨论](https://github.com/yagyeshVyas/VibeGuard/discussions)。 © 2026 Yagyesh Vyas。基于 MIT 许可证发布。
标签:CISA项目, DOE合作, MITM代理, StruQ, 人工智能安全, 代码安全, 合规性, 安全扫描, 对抗攻击, 开发安全工具, 敏感信息检测, 时序注入, 暗色界面, 漏洞枚举, 自动化payload嵌入, 自定义脚本, 错误基检测, 静态代码分析