myguard-labs/vaultwarden-crs-plugin
GitHub: myguard-labs/vaultwarden-crs-plugin
面向 Vaultwarden 的 OWASP CRS 插件,提供精确的误报排除规则和可选的正向安全路径白名单,让 Core Rule Set 能正确适配 Vaultwarden 的 API 路由。
Stars: 2 | Forks: 0
# Vaultwarden (Bitwarden) OWASP CRS 插件
    

一个直接可用的 [OWASP CRS](https://coreruleset.org/) 插件,使 Core
Rule Set 能够与 **[Vaultwarden](https://github.com/dani-garcia/vaultwarden)**
(兼容 Bitwarden 的 Rust 服务器)完美配合 —— 并且(可选地)将主机
锁定在 Vaultwarden 已知的路由表中。
它主要做两件事:
1. **误报排除** (`vaultwarden-before.conf`) —— 精确的、
主机范围的排除规则,使得合法输入(Argon2 管理 `token`、
`/identity/connect/token` 上的 OAuth 密码授权哈希、
`/api` 下的 EncString 加密/账户/发送数据块、用户提供的图标
域名)不会触发 CRS。
2. **正向安全 / 路径白名单** (`vaultwarden-after.conf`,
**可选开启**) —— *允许 Vaultwarden 的真实路由,拒绝其他所有路由*。
任何不在 Vaultwarden 挂载点(`/api`、`/identity`、
`/admin`、`/events`、`/icons`、`/notifications`、`/attachments`、
内置静态路由和 web-vault 静态目录树)中的路径都会被拒绝。这
可以在常见的 `/.env` / `/wp-login.php` 扫描器噪音到达
后端之前将其阻止,而无需考虑 payload。**没有参数名白名单**(见上文)。
路由表源自 Vaultwarden 的源码
(`src/main.rs` 挂载点 + `src/api/web.rs` 静态路由)**以及**
从 `vaultwarden/server:latest` 提取的内置 `web-vault` 静态目录树 — — 而
非随意猜测。最后一次重新校验对应的源码 commit 为 `169aa5e`。
正向安全层还会:强制执行 **HTTP 方法
白名单**(仅允许 `GET/POST/PUT/DELETE/HEAD/OPTIONS` —— `TRACE`、`CONNECT`、
`PATCH` 及垃圾动词会被拒绝,`9530220`);要求 `/api` 中的写操作使用 **`application/json`**
(除了 multipart 的 `/api/sends/file*` 和 cipher 附件
上传,`9530225`);**将静态文件扩展名锚定到单个路径
片段**,这样像 `/x/y/z.json` 这样深层的伪造路径就不会再漏网;并且
**在每次拦截时将其计入 CRS 的入站异常评分**,从而让 fail2ban / CRS DOS
层能够察觉到这些探测,而不是无声息地返回 404。
## 要求
- CRS 版本 4.0 或更高
- 兼容 ModSecurity 的 Web 应用防火墙
## 安装
将这三个文件复制到你的 CRS `plugins/` 目录中:
```
plugins/vaultwarden-config.conf
plugins/vaultwarden-before.conf
plugins/vaultwarden-after.conf
```
CRS 会先加载 `plugins/*-config.conf`,接着加载 `*-before.conf`(在规则之前),
然后再加载 `*-after.conf`(在规则之后),这一切都是自动完成的。
## 配置
编辑 `vaultwarden-config.conf`:
| 变量 | 默认值 | 含义 |
|---|---|---|
| `tx.vaultwarden-plugin_enabled` | `0` | 主开关。**默认关闭** —— 该插件会放宽 Vaultwarden 路由上的 CRS 限制,因此必须按 vhost 单独启用,而不能全局启用。仅在 Vaultwarden 的 server/location 块中将其设置为 `1`(参见部署说明)。 |
| `tx.vaultwarden-plugin_positive_security` | 跟随 `_enabled` | 开启/关闭路径白名单层。默认跟随启用标志;在启用块中显式设置为 `0` 可在仅运行排除规则时不使用白名单。 |
| `tx.vaultwarden-plugin_argname_allowlist` | `0` | 实验性的、**独立**的参数名白名单可选开启(`9530240` token 表单字段,`9530245` GET 查询名称)。**不**跟随 `_enabled`;仅在经过 DetectionOnly 试运行后启用。 |
作用域的控制完全由按 vhost 的启用标志决定 —— **没有** Host **门控**。仅在 Vaultwarden vhost 上启用该插件,例如(Angie /
nginx + libmodsecurity3):
```
server {
server_name vault.example.com;
modsecurity on;
modsecurity_rules '
SecAction "id:9530001,phase:1,nolog,pass,setvar:tx.vaultwarden-plugin_enabled=1"
';
# ...
}
```
在 Apache/mod_security2 上,将相同的变量设置在匹配的
`` / `` 块内。
## 部署说明
1. 安装后,仅在 Vaultwarden vhost 中启用插件
(`setvar:tx.vaultwarden-plugin_enabled=1`)。排除规则立刻生效且安全,
永远不会触及同一 CRS 引擎上的其他 vhost。
2. 在 **DetectionOnly** 模式下运行 CRS,并观察审计日志中是否有 `9530230` 命中
—— 这些是路由白名单中缺失的路径。如果你在 Vaultwarden 前端
配置了额外路由(反向代理健康检查、自定义
连接器),请将它们添加到 `vaultwarden-after.conf` 中规则
`9530230` 的内联白名单正则表达式中。
3. 将 CRS 切回阻断模式。
规则 ID 范围:**9,530,000 – 9,530,999**(阻断基数为 9,530,000;已在
[CRS 插件注册表](https://github.com/coreruleset/plugin-registry)中声明为空闲,
等待正式分配)。
## 持续集成
每次 push/PR 都会运行六个 GitHub Actions 工作流(除 Lint 外,其他均在上方显示徽章):
| 工作流 | 功能描述 |
|---|---|
| **Lint** | 本地规则 ID 范围 (9530000–9530999) / 重复 ID / `@pmFromFile` / 测试引用检查,然后运行官方的 `coreruleset/crs-plugin-test-action` lint。 |
| **集成测试** | 插件结构门控(无主机门控、可选白名单、**无 `ARGS_NAMES` 白名单**、条件化配置默认值、每条规则包含 `ver:`)。 |
| **Apache + ModSecurity v2** | 构建共享的 CRS+插件镜像,并在真实的 Apache httpd + mod_security2 上运行 go-ftw 回归测试套件(`apache2ctl -t` 用于解析门控)。 |
| **nginx + libmodsecurity3** | 在 Angie + libmodsecurity3 3.0.14 上运行相同的镜像 —— 这是一个生产环境的镜像(`angie -t` 用于解析门控)。 |
| **Coraza 兼容性** | 将每个插件文件加载到 `coraza.NewWAF()` 中(位于 [`tests/coraza/`](tests/coraza/) 的 vendored 探针)—— 在配置加载阶段,Coraza 遇到问题会直接报错,而 ModSecurity 仅仅发出警告,因此这可以作为第三种引擎的门控,并重放运行时事务以证明规则确实被*触发*(加载成功 ≠ 被触发)。在 PR 上运行。 |
| **安全语料库** | 针对已启用的插件重放真实扫描器/探测路径的语料库,以证明路径/方法白名单确实拒绝了它们(针对尾部斜杠和深层嵌套绕过类别的回归测试防护)。 |
双引擎测试工具位于 [`tests/integration/`](tests/integration/);
go-ftw 测试用例位于 [`tests/regression/`](tests/regression/) 和
[`tests/security/`](tests/security/)。
## 禁用插件
将 `tx.vaultwarden-plugin_enabled` 设置为 `0`(默认值),或者直接将插件
文件从 `plugins/` 目录中删除。
## 边缘加固(速率限制,原生路径/方法白名单)
CRS 插件是 WAF 防御的一部分。关于**边缘防御部分** —— 按端点的速率
限制 (`/admin`、`/identity/connect/token`、注册、send 下载)、
对未知路由返回 404 的原生路径白名单、方法白名单、安全
请求头以及请求体/超时限制 —— 请参见 [`contrib/angie/vault.conf`](contrib/angie/vault.conf)
和 [`contrib/README.md`](contrib/README.md)。
特别是速率限制 **无法** 在插件中完成:libmodsecurity3
(v3) 没有持久的按 IP 收集功能,因此它应该部署在边缘(或
fail2ban 中)。将插件和 contrib vhost 结合运行以实现双重保险。
## 报告误报
提交新的 issue 或 pull request。对于 issue,请包含:
- CRS 版本
- ModSecurity/Coraza 版本
- modsec 审计日志
- 导致误报的原因
## 另请参阅
- Vaultwarden:
- 撰写的文章 / 部署指南:[Self-Hosted Vaultwarden on deb.myguard.nl](https://deb.myguard.nl/2026/05/self-hosted-password-manager-with-vaultwarden/)
- ViMbAdmin CRS 插件(同一作者,带有参数名白名单的表单应用变体):
标签:AppImage, EVTX分析, ModSecurity, OWASP CRS, Vaultwarden, WAF规则, Web应用防火墙, 白名单, 误报排除, 请求拦截