你的 AI 写代码的速度比你阅读它的速度还要快。这就是它的意义所在,而且这种情况不会
消失。
问题在于没人去读它。Veracode 测试了 100 多个模型,发现 **45% 的生成代码引入了 OWASP Top 10 漏洞** —— 而更新、更大的
模型并没有表现更好。Escape.tech 扫描了 5,600 个基于
Lovable、Bolt 和 Base44 构建的生产级应用,发现了 **2,000 多个漏洞和 400 多个暴露的活密钥。** 佐治亚理工学院的 Vibe Security Radar 追踪到 **74 个 CVE 源于特定的 AI 工具提交**,仅在 2026 年 3 月就有 35 个。
所有现有工具都是在代码生成*之后*才告诉你这些问题。扫描器在 CI 中运行。审查在 PR 阶段进行。WAF 部署在生产环境中。它们全都处于漏洞产生那一刻的下游 —— 而到那时,它已经存在于你的 git 历史、构建过程中,并且很可能已经部署了。
**Slopguard 将检查前移到了“模型生成代码”到“它写入磁盘”之间的那一秒钟。**
那不是你随手滑过的 linter 警告。写入操作没有发生。
请注意中间的关键步骤:拦截块向模型传递了一个规则 ID 和具体的修复方案,因此
它可以自我纠正并继续执行。大多数时候你什么都不用做 —— 你只需看着它在第二次尝试时就能做对。
## 两个层级
**1. `AGENTS.md` —— 18 条编号规则。** 一个可移植的安全准则,
Claude Code、Cursor、Copilot、Windsurf、Cline、Aider 和 Codex 都能读取。将其放入
任何 repo 中。到处都适用,但不强制执行任何内容。
**2. Claude Code 插件 —— 真正能拦截的 hooks。** 因为模型可以忽略的建议算不上是控制。四个 hooks 实时拦截工具调用,拒绝不安全的调用,并向模型提供规则 ID 和具体的修复方案,使其能够自我纠正,而不是瞎猜。
规则用于教导。Hooks 用于执行。这两者你都需要。
## 安装
```
# 在 Claude Code 中
/plugin marketplace add manpreet171/slopguard
/plugin install slopguard@slopguard
```
然后将规则放入你正在处理的任何项目中:
```
curl -O https://raw.githubusercontent.com/manpreet171/slopguard/main/AGENTS.md
```
就是这样。无需配置,无需 API key,无依赖 —— 这些 hooks 是仅使用标准库的纯 Node ESM
脚本。重启 Claude Code,防护机制即生效。
本地安装,或不使用插件系统
```
git clone https://github.com/manpreet171/slopguard
# 在 Claude Code 中:
/plugin marketplace add ./slopguard
/plugin install slopguard@slopguard
```
要手动连接 hooks,请将 `plugins/slopguard/hooks/hooks.json` 复制到你的 `.claude/settings.json` 中,并将 `${CLAUDE_PLUGIN_ROOT}` 替换为 `plugins/slopguard` 的路径。
完全不使用 Claude Code?仅凭 `AGENTS.md` 在 Cursor、
Copilot、Windsurf 和 Aider 中依然能发挥实际作用。请参阅 [便携式使用](#portable-use)。
## 拦截了什么
以下是此 repo 中测试套件的真实输出 —— 并非模拟。
### 硬编码的 key 和字符串拼接的查询
```
✗ SLOPGUARD blocked this write to src/server/db.js — 2 unsafe pattern(s):
• [SG-1] Stripe live secret key
found: sk_live_51H8…ijkX
fix: Move this to an environment variable or a secret manager, reference it
via process.env, and rotate the exposed credential — assume it is
already public.
• [SG-2] SQL built by string interpolation
found: SELECT * FRO…ail}
fix: Use a parameterized query. Pass values as bound arguments, never
concatenate them into the SQL string.
```
注意脱敏处理 —— Slopguard 绝不会将真实的凭证回显到你的记录中。
### React 组件中的 `service_role` key
这是 Lovable/Bolt/Base44 类应用中最灾难性的错误。
```
✗ SLOPGUARD blocked this write to src/lib/supabase.ts:
• [SG-6] Supabase service_role key in client-reachable code
fix: This file ships to the browser. A service_role key there bypasses every
Row Level Security policy you wrote — any visitor gets full database
access. Use the anon key on the client and keep privileged calls behind
a server route or Edge Function.
```
### 幻觉包
Slopguard 会在**运行安装之前**查询 npm 和 PyPI。404 意味着这是幻觉。
```
✗ SLOPGUARD blocked this install — [SG-4] 2 package(s) do not exist:
• express-mongoose-helper-utils (npm: 404 not found)
• react-query-toolkit-pro (npm: 404 not found)
```
一个*确实*存在但仅在 11 天前发布的包也会被标记 —— 这就是从内部看到的“垃圾蹲守”(slopsquat)的样子。
### 你自己的规则文件被投毒
在会话开始时、模型读取它们之前进行检查:
```
⚠ SLOPGUARD PRE-FLIGHT
[SG-16] HIDDEN UNICODE in CLAUDE.md — line 1 (ZERO WIDTH SPACE, RIGHT-TO-LEFT OVERRIDE)
This file steers the agent. Invisible characters here are the "Rules File
Backdoor" technique: directives the model reads and a reviewer cannot see.
[SG-16] MCP/SETTINGS CHANGED since last session: .mcp.json
Diff it before you let the agent run. This is the MCPoison pattern
(CVE-2025-54136): a previously-approved entry whose command was swapped.
```
## 为什么是这四项检查
并非随意决定。每一项都对应着一个已记录、已发生的真实攻击:
| 防护 | 防御对象 | 来源 |
|---|---|---|
| 安装前进行 registry 验证 | **Slopsquatting。** 19.7% 的 AI 推荐包并不存在;43% 的虚假名称在每次重新运行时都会重复出现,因此攻击者会挖掘模型并注册它们。 | [USENIX Security 2025](docs/THREATS.md#slopsquatting-hallucinated-packages-as-a-supply-chain) |
| 指令文件扫描 | **Rules File Backdoor。** `CLAUDE.md` / `.cursor/rules` 中不可见的 Unicode 携带着模型会服从但审查者无法察觉的指令。规则文件会被共享,因此它会传播。 | [Pillar Security](docs/THREATS.md#the-rules-file-backdoor) |
| 配置漂移检测 | **MCPoison (CVE-2025-54136)。** 在共享的 repo 中,已批准的 MCP 条目命令被悄悄替换 -> 持久的 RCE。 | [Check Point](docs/THREATS.md#cve-2025-54136--mcpoison-cvss-72) |
| 写入时代码检查 | **那 45%。** Secrets、注入、弱加密、不安全的反序列化 —— 这些因为循环中没有任何检查而反复发生的机械性故障。 | [Veracode](docs/THREATS.md#ai-generated-code-fails-security-tests-at-a-measurable-rate) |
包含指向每个原始来源链接的完整证据:**[docs/THREATS.md](docs/THREATS.md)**
## 规则
| | | | |
|---|---|---|---|
| **SG-1** 代码中绝不包含 Secrets | **SG-2** 仅使用参数化查询 | **SG-3** 禁止动态 shell 或 eval | **SG-4** 验证每个依赖项 |
| **SG-5** 加固 session cookies | **SG-6** 在数据层进行 Authz | **SG-7** 每个路由的对象级 authz | **SG-8** 现代 crypto 和 CSPRNG |
| **SG-9** 安全反序列化 | **SG-10** CORS、CSRF、JWT | **SG-11** 受限的出站请求 (SSRF) | **SG-12** 速率限制和锁定 |
| **SG-13** 错误信息零泄漏 | **SG-14** 干净的日志,无 PII | **SG-15** 安全的路径和上传 | **SG-16** Agent 供应链 |
| **SG-17** 边界处的 schema 验证 | **SG-18** 保持 TLS 验证开启 | | |
其中九项是机器强制的。其余的由你掌握 —— 请阅读 **[AGENTS.md](AGENTS.md)**。
这些规则是*写给模型*的,采用第二人称,并包含了
推理过程。这很重要:理解为什么 `jwt.decode` 不安全的模型能够举一反三处理下一个案例。而仅仅匹配被禁字符串的模型做不到这点。
## Skills 和 Red teamer
三个模型会自动调用、或者你也可以直接调用的 skills:
```
/slopguard:threat-model # before you build — assets, entry points, what a human must own
/slopguard:harden # audit a feature against SG-1..SG-18, then fix it
/slopguard:preflight # before deploy — git history, RLS, client bundle, CVEs
```
外加一个以攻击者而非 linter 的视角进行审查的对抗性子代理(subagent):
```
@slopguard:redteam review the checkout flow
```
它会优先查看核心资产 —— 对象级授权、多租户泄漏、认证状态机、业务逻辑 —— 并且只报告具有具体攻击路径的发现。它的指令是,当一切安全时说“clean”,绝不为了凑数而填充列表。
## Slopguard 不包含什么
夸大其覆盖范围的安全工具比没有更糟,因为它会
制造虚假的信心。所以,明确地说:
- **不是 SAST 的替代品。** 它在写入时捕获高置信度的模式。
在 CI 中也要运行 Semgrep、CodeQL 或 Snyk。不同的层级,不同的工作。
- **它无法找到缺失的授权。** 任何模式匹配器都做不到 —— 缺失的检查不是模式。这就是 `/slopguard:harden` 和 red team agent 存在的意义,也是最终人类审查存在的意义。
- **它只能看到 agent 写入的代码。** 你自己粘贴的代码,或通过 `git pull` 到达的代码,在写入时不会被检查。
- **registry 检查需要网络。** 超时时它会直接放行 —— 一个在断网时阻碍你工作的防护机制,最终只会被你卸载。
- **它可以被绕过。** 任何下定决心绕过它的人都能做到。它是护栏,不是沙盒。它的存在是为了让安全路径成为默认路径。
它不会回传数据、收集遥测信息或将你的代码发送到任何地方。唯一的
网络请求是向 `registry.npmjs.org` 和 `pypi.org` 发出的,以查询某个包是否
存在。
## 调优
觉得噪音太大?每条规则都存在于一个可读性极强的文件中:
[`plugins/slopguard/scripts/rules.mjs`](plugins/slopguard/scripts/rules.mjs)。
模式被标记为 `deny`(已被证明不安全 —— 阻止)或 `ask`(启发式 —— 提示你)。移动任何你不同意的规则,或者将其添加到 `ALLOWLIST_PATHS`。
测试文件、`node_modules`、lockfiles 和 `.env.example` 已被跳过。
```
npm test # 47 cases: 22 must block, 4 must prompt, 21 must stay silent
# 或手动检查单个 payload
echo '{"tool_input":{"file_path":"a.js","content":"YOUR CODE"}}' \
| node plugins/slopguard/scripts/guard-write.mjs
```
近一半的测试套件专门用于测试*绝对不应*触发规则的代码 ——
参数化查询、读取 `process.env`、bcrypt、加固的 cookies、anon keys、
`.env.example` 占位符。这些才是真正重要的测试。
如果某条规则对安全代码触发了,那是一个值得提 issue 的 bug —— 误报是导致防护机制被关闭的原因,而一个被关闭的防护机制等于毫无防御。
## 便携式使用
`AGENTS.md` 是纯 markdown 文件,没有任何 Claude 特定的语法。它可以直接在以下工具中使用:
| 工具 | 存放位置 |
|---|---|
| Claude Code | 项目根目录中的 `AGENTS.md` 或 `CLAUDE.md` |
| Cursor | `.cursor/rules/slopguard.mdc` 或 `.cursorrules` |
| GitHub Copilot | `.github/copilot-instructions.md` |
| Windsurf | `.windsurfrules` |
| Cline / Aider / Codex | 项目根目录中的 `AGENTS.md` |
目前强制执行仅支持 Claude Code。欢迎移植。
## 仓库布局
```
AGENTS.md the 18 rules — portable, drop in any repo
CLAUDE.md pointer so Claude Code loads them
docs/THREATS.md every claim, with primary sources
plugins/slopguard/
hooks/hooks.json hook wiring
scripts/
rules.mjs the entire detection library, one file
guard-write.mjs PreToolUse: Write | Edit | MultiEdit
guard-bash.mjs PreToolUse: Bash — registry verification
guard-session.mjs SessionStart: instruction + config integrity
skills/ threat-model, harden, preflight
agents/redteam.md adversarial reviewer
```
## 许可证
MIT。请参阅 [LICENSE](LICENSE)。
由 Manpreet Singh 构建
LinkedIn ·
Medium ·
Email
Vibe coding 不是问题。不加阅读就发布才是问题。