WebGuard
为LLM代理提供安全的web获取MCP服务器。扫描获取内容以进行快速注入攻击 之前 它进入LLM上下文窗口。恶意内容被完全阻止——零泄漏令牌。
Rust重写 网络卫士mcp(Go)相同的安全模型,相同的测试套件,更小的二进制文件,没有GC暂停。
改变了什么(Go→ Rust)
- 二进制:6MB对比10MB
- 无垃圾收集器 --一致的亚毫秒扫描延迟
- BurntSushi's aho corasick --ripgrep等级模式匹配
- 流媒体正文读取 --在下载过程中强制执行大小限制,而不是在下载后
- 每跳重定向SSRF验证 --根据阻止列表重新检查每个重定向
- 相同的38种内置模式,相同的两级级联,相同的SSRF保护
安装
# Homebrew (macOS/Linux)
brew install mark-liu/tap/webguard
# Cargo (from crates.io)
cargo install webguard
# From source
git clone https://github.com/mark-liu/webguard
cd webguard
cargo build --release
# Binary at target/release/webguard用法
# Add to Claude Code
claude mcp add webguard -s user -- /path/to/webguard
# Then use webguard_fetch in Claude Code to retrieve any URL建筑
Claude Code → webguard_fetch(url)
│
┌───────────┴───────────┐
│ 1. URL Validation │ SSRF prevention, scheme check
│ 2. DNS Pinning │ Resolve + validate all IPs
│ 3. HTTP Fetch │ HTTPS, streaming body, retry
│ 4. Redirect Recheck │ Re-validate SSRF on every hop
│ 5. Content Extraction │ HTML → markdown, strip scripts
│ 6. Preprocessing │ Comment extraction, entity decode,
│ │ base64/URL/hex decode, NFC normalize,
│ │ zero-width strip
│ 7. Stage 1: Patterns │ Aho-Corasick + regex (~0.3ms)
│ ↳ Category filter │ Suppress per-domain categories
│ ↳ Doc-path hints │ Auto-suppress for /docs/, /api/
│ 8. Stage 2: Heuristic │ Density, clustering, proximity
│ 9. Decision │ PASS/WARN/BLOCK based on mode
│ 10. Audit Log │ JSONL with pattern IDs + timing
└───────────────────────┘工具
webguard_fetch
获取具有SSRF保护和提示注射扫描的URL。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url | string | yes | 要获取的URL(http/https) |
headers | object | 否 | 自定义HTTP标头 |
raw | boolean | no | 返回原始HTML而不是markdown |
max_chars | number | no | 截断对N个字符的响应(0=无限制) |
在PASS上:返回提取的markdown内容+元数据。 关于警告 (mode=warn):返回带有警告横幅+元数据的内容。 在块上 (模式=块,默认):返回 [BLOCKED: prompt injection detected] +元数据。零页面内容泄露。
webguard_status
返回服务器运行状况:版本、模式计数、模式、灵敏度、配置。
webguard_report
返回从JSONL审计日志聚合的审计报告。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
days | number | no | 要包含的天数(默认值:7) |
测试页面
用于验证检测的实时测试页面:https://mark-liu.github.io/webguard/test/
| 页面 | 预期 | 类别 |
|---|---|---|
| clean.html | 通过 | -- |
| inject.html | block | 指令重写(HTML注释) |
| exfil.html | 封锁 | 撤离指令 |
| encoded.html | block | 指令重写(base64) |
| authority.html | 阻止 | 权限声明 |
分类器
两阶段级联——快速模式匹配,然后仅在需要时进行启发式评分。
第一阶段:模式匹配
通过混合Aho-Corasick(字面量,单O(N)通道)+正则表达式(结构模式),在8个类别中有38个内置模式。可以从外部YAML文件加载其他模式。
| 类别 | 图案 | 描述 |
|---|---|---|
| 指令覆盖 | 7 | 尝试覆盖或重置之前的指令 |
| 提示标记 | 6 | 伪造的系统/指令分隔符和聊天标记 |
| 权限声明 | 6 | 对开发人员、管理员或提升访问权限的虚假声明 |
| exil指令 | 5 | 通过URL或隐藏元素进行数据泄露 |
| 输出操作 | 4 | 尝试约束或重定向模型输出 |
| unicode混淆 | 4 | 零宽度字符、RTL重写、专用区域 |
| 编码注入 | 3 | Base64/eval/字符码混淆有效载荷 |
| 分隔符注入 | 3 | 伪提示边界和角色注入 |
看 PATTERNS.md 查看带有示例和正则表达式定义的完整模式列表。
类别抑制
抑制每个域的特定模式类别以消除误报:
domains:
"*.linkedin.com":
suppress: ["authority-claim"]
"interactivebrokers.com":
suppress: ["encoded-injection"]文档URL(/docs/, /api/, /reference/, /sdk/等)自动抑制 exfil-instruction 和 encoded-injection.
第二阶段:启发式评分
仅在第一阶段发现非关键匹配时运行。因素:
- 密度:每1000个字符匹配(>2.0=1.2倍乘数)
- 聚类:相互匹配在200个字符以内(1.5倍)
- 邻近:权限声明+附近的指令覆盖(1.5倍)
- 编码惩罚:解码内容匹配(1.3x)
灵敏度级别
| 级别 | 阈值 | 用例 |
|---|---|---|
low | 2.0 | 文档、可信来源 |
medium | 1.0 | 常规浏览(默认) |
high | 0.5 | 来源不可信 |
SSRF预防
任何TCP连接前的所有检查:
- 私有IP范围(RFC 1918、环回、链路本地、运营商级NAT)
- 云元数据(AWS、GCP、Azure、阿里巴巴、Oracle、ECS)
- 八进制IP检测(
0177.0.0.01) - URL编码主机名拒绝
@URL权限拒绝- DNS固定(解析一次,连接到解析的IP)
- 在每次重定向跳转时重新验证 (最多5个)--防止DNS重新绑定和重定向到内部旁路
配置
~/.config/webguard-mcp/config.yaml --使用零配置(合理的默认值):
sensitivity: medium
mode: block
max_body_size: 5242880
request_timeout: 15s
patterns_dir: ""
domains:
"docs.python.org":
sensitivity: low
timeout: 30s
"*.github.com":
sensitivity: low
"*.linkedin.com":
suppress:
- authority-claim
allowlist: []
blocklist: ["*.evil.com"]
audit:
enabled: true
path: "" # default: ~/.local/share/webguard-mcp/audit.jsonl外部图案
通过将YAML文件放置在 patterns_dir 目录:
# patterns.d/custom.yaml
patterns:
- id: custom-001
category: instruction-override
severity: high
type: literal
value: "override all safety measures"发展
cargo build # Build debug binary
cargo test # Run all 77 tests
cargo build --release # Build optimised binary
cargo clippy # Lint
cargo fmt --check # Format check项目结构
webguard/
├── src/
│ ├── main.rs # CLI entry, signal handling, MCP boot
│ ├── server.rs # MCP tool handlers (fetch/status/report)
│ ├── config.rs # YAML config, domain overrides
│ ├── audit.rs # JSONL audit logger + reader
│ ├── fetch/
│ │ ├── ssrf.rs # URL + IP validation, DNS pinning
│ │ ├── client.rs # HTTP fetch, redirect recheck, retry
│ │ └── extract.rs # HTML → markdown
│ └── classify/
│ ├── engine.rs # Two-stage orchestrator
│ ├── preprocess.rs # 8-step content preprocessing
│ ├── stage1.rs # Aho-Corasick + regex scanner
│ ├── stage2.rs # Heuristic scoring
│ ├── patterns.rs # 38 built-in patterns
│ ├── external.rs # External pattern YAML loader
│ ├── encoding.rs # Base64/URL/hex/ROT13 decode
│ └── result.rs # Result types
├── docs/test/ # GitHub Pages test pages
├── testdata/ # Test fixtures (14 JSON files)
└── patterns.d/ # External pattern directory相关项目
- 网络卫士mcp --原始的Go实现(被此仓库取代)
- 麦普加德 --MCP stdio代理,扫描来自任何MCP服务器(Discord、Telegram等)的工具结果,以便及时注入
- 折断 --用于Playwright快照的MCP stdio压缩代理
许可证
麻省理工学院
