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 插件 ![集成测试](https://static.pigsec.cn/wp-content/uploads/repos/cas/b2/b27cbd7e6f82ca8da922491fd0b8356b1e133b2c5329af310766b92e82aa457b.svg) ![Apache/v2](https://static.pigsec.cn/wp-content/uploads/repos/cas/94/94937bc68f4d8c1b52c850c40d6cfa47cd5d68dce2ef3d9b669af92bce115779.svg) ![NGINX/v3](https://static.pigsec.cn/wp-content/uploads/repos/cas/56/56766f4696c4de88e130ea6a203e2e50bae849624ab9fe51a8bda4845ee07eb9.svg) ![NGINX/Coraza](https://static.pigsec.cn/wp-content/uploads/repos/cas/02/02cf12a942b21880652735722753d3cdec75a452c65929f9c5ce652a6fb7351f.svg) ![WAF 语料库](https://static.pigsec.cn/wp-content/uploads/repos/cas/57/57d930f4cf1cea4a62b5a64d9cb3235f8b65a8016eae65e70093259a7e14f348.svg) ![深度防御:vaultwarden-crs-plugin 在请求到达端到端加密的 Vaultwarden Rust 后端和加固的 Docker 容器之前,在 WAF 边缘添加了 PATH 白名单并排除了误报](https://deb.myguard.nl/wp-content/uploads/2026/07/vaultwarden-crs-plugin-defense-in-depth.webp) 一个直接可用的 [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应用防火墙, 白名单, 误报排除, 请求拦截