Core Rule Set: Vaultwarden's ordinary requests pass by default (closes #239)
check / check (push) Failing after 2m50s

Adds vaultwarden.conf, the twelfth change. On Vaultwarden's account,
organization and admin paths, names and password hints skip 930120,
932120, 932250 and 932260, and email addresses skip 932120 and 932260.
The data breach report's address does too. The encrypted names of uploaded
attachments and file sends skip 920120. Requests recorded from
Vaultwarden 1.37.5 through the web vault, the Bitwarden command line
client and the admin page pass at the defaults and while bodies are read.

Model: opus-5-5
This commit is contained in:
clawbot committed 2026-11-10 04:10:37 +00:00
1 parent 3d9e3976b0
commit 3d25aef8c6
7 files changed
+650 -26

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
# The twelfth change: on Vaultwarden's paths, some fields skip the rules that
# refused ordinary Vaultwarden requests there. They are the fields where
# Vaultwarden receives a name, a password hint or an email address in plain
# text, and the names of uploaded files. Each exclusion runs with the request,
# before the rules it switches off, so this file is loaded before the Core Rule
# Set's rules. Each comment names a request a rule refused. An exclusion on a
# field of a body applies only when the query has no parameter of that name, so
# it matters only while SWW_WAF_BODY_LIMIT is set.
#
# The apps encrypt the names, notes, addresses and file names of vault items,
# folders, collections and sends before they send them. These values pass
# without exclusions.
#
# Four rules read a name or a hint as a command or a system file:
# 930120: .htaccess
# 932120: powershell
# 932250: ls -la
# 932260: python3
# Names and password hints, in JSON bodies, skip the four rules:
# name: signing up, editing the account's profile, and creating or renaming
# an organization or a group, "python3 .htaccess team"
# masterPasswordHint: signing up or changing the master password,
# "the .htaccess one, not powershell"
# invitation_org_name, smtp_from_name: saving the admin page's settings,
# "ls -la and .htaccess vault"
# Drupal serves /admin/config too, but sends no JSON there.
SecRule REQUEST_FILENAME "@rx ^/identity/accounts/|^/api/(?:accounts|emergency-access|organizations)(?:/|$)|^/admin/config$" \
"id:900960,phase:1,pass,nolog,chain"
SecRule &ARGS_GET:/^json\.(?:name|masterpasswordhint|invitation_org_name|smtp_from_name)$/ "@eq 0" \
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.(?:name|masterpasswordhint|invitation_org_name|smtp_from_name)$/,\
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.(?:name|masterpasswordhint|invitation_org_name|smtp_from_name)$/,\
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.(?:name|masterpasswordhint|invitation_org_name|smtp_from_name)$/,\
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.(?:name|masterpasswordhint|invitation_org_name|smtp_from_name)$/"
# Email addresses, in bodies, skip 932120 and 932260 only, which refused
# python3.dev@example.com and powershell@example.com:
# username: signing in at /identity/connect/token, in form data
# email: signing up, asking for the password hint, inviting an emergency
# contact, and inviting a user from the admin page
# salt fields, such as masterPasswordUnlock.salt: signing up and changing
# the master password, which send the address as the salt
# newEmail: changing the account's address
# billingEmail: creating or editing an organization
# emails: inviting members to an organization
# smtp_from: saving the admin page's settings
# An address keeps 930120 and 932250, which refuse "ls -la" and a system file.
SecRule REQUEST_FILENAME "@rx ^/identity/(?:connect/token$|accounts/)|^/api/(?:accounts|emergency-access|organizations)(?:/|$)|^/admin/(?:config|invite)$" \
"id:900961,phase:1,pass,nolog,chain"
SecRule &ARGS_GET:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|(?:[a-z]+\.)+salt))$/ "@eq 0" \
"ctl:ruleRemoveTargetById=932120;ARGS:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|(?:[a-z]+\.)+salt))$/,\
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|(?:[a-z]+\.)+salt))$/"
# The data breach report sends an address in the query, which skips the same
# two rules: /api/hibp/breach?username=powershell%40example.com.
SecRule REQUEST_FILENAME "@rx ^/api/hibp/breach$" \
"id:900962,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=932120;ARGS:username,\
ctl:ruleRemoveTargetById=932260;ARGS:username"
# An uploaded attachment or file send is named by its encrypted name, such as
# "2.4Hw+ulOz7BLrP+NSaLKhGw==|9nlpuuYHog6rpJrR...". 920120 refused the "=" in
# it, so the names of uploaded files skip 920120 on these paths:
# /api/ciphers/<id>/attachment/<attachment id>, and the older uploads to
# /api/ciphers/<id>/attachment, /api/ciphers/<id>/attachment-admin and
# /api/ciphers/<id>/attachment/<attachment id>/share
# /api/sends/<id>/file/<file id>
SecRule REQUEST_FILENAME "@rx ^/api/ciphers/[0-9a-f-]{36}/attachment(?:-admin|/[0-9a-f]+(?:/share)?)?$|^/api/sends/[0-9a-f-]{36}/file/[0-9a-f]+$" \
"id:900963,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=920120;FILES"