Files
smallwebwaf/internal/coreruleset/vaultwarden.conf
T
sneak b2f6be366e
check / check (push) Failing after 3m40s
Read every setting through viper and rename the settings (closes #211)
Every setting of discriminator and rproxy is read through viper, in place
of the os.LookupEnv function Main passed down. NewViper turns AutomaticEnv
and AllowEmptyEnv on, so a setting that is set but empty reads as set. A
setting may also be given as a file, the _FILE form, which rproxy's
settings now have too; rproxy still writes nothing to disk.

The settings are renamed. Discriminator's take the prefix SWW_WAF_,
rproxy's take SWW_RPROXY_, and the shared SWW_COMMAND keeps SWW_. The Core
Rule Set's settings take SWW_WAF_CORE_RULE_SET_ rather than SWW_WAF_WAF_.

Model: deepseek-v4-pro (first version); opus-5-5 (rework)
2026-11-10 08:46:11 +00:00

85 lines
5.6 KiB
Plaintext

# The thirteenth 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_CORE_RULE_SET_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"
# name: naming a security key at /api/two-factor/webauthn, "python3 key"
# 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)(?:/|$)|^/api/two-factor/webauthn$|^/admin/config$" \
"id:900150,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 930120, 932120 and 932260, which refused
# these addresses:
# 930120: jane.profile@example.com
# 932120: powershell@example.com
# 932260: python3.dev@example.com
# These fields hold an address:
# 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
# email: setting up sign-in codes by email, and asking for one when signing
# in, under /api/two-factor/
# email: signing in with another device, at /api/auth-requests
# email: sending the admin page's test email, at /admin/test/smtp
# salt fields, such as masterPasswordUnlock.salt: signing up and changing
# the master password, which send the address as the salt
# accountUnlockData.masterPasswordUnlockData.email: rotating the account's
# encryption key
# newEmail: changing the account's address
# billingEmail: creating or editing an organization
# emails: inviting members to an organization
# smtp_from, smtp_username, org_creation_users: saving the admin page's
# settings
# An address holds no spaces, so it keeps 932250, which needs ls -la.
SecRule REQUEST_FILENAME "@rx ^/identity/(?:connect/token$|accounts/)|^/api/(?:accounts|emergency-access|organizations|auth-requests)(?:/|$)|^/api/two-factor/|^/admin/(?:config|invite|test/smtp)$" \
"id:900151,phase:1,pass,nolog,chain"
SecRule &ARGS_GET:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|smtp_username|org_creation_users|(?:[a-z]+\.)+salt|accountunlockdata\.masterpasswordunlockdata\.email))$/ "@eq 0" \
"ctl:ruleRemoveTargetById=930120;ARGS:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|smtp_username|org_creation_users|(?:[a-z]+\.)+salt|accountunlockdata\.masterpasswordunlockdata\.email))$/,\
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|smtp_username|org_creation_users|(?:[a-z]+\.)+salt|accountunlockdata\.masterpasswordunlockdata\.email))$/,\
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:username|json\.(?:email|newemail|billingemail|emails\.\d+|smtp_from|smtp_username|org_creation_users|(?:[a-z]+\.)+salt|accountunlockdata\.masterpasswordunlockdata\.email))$/"
# The data breach report sends an address in the query, which skips the same
# three rules: /api/hibp/breach?username=jane.profile%40example.com.
SecRule REQUEST_FILENAME "@rx ^/api/hibp/breach$" \
"id:900152,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=930120;ARGS:username,\
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:900153,phase:1,pass,nolog,\
ctl:ruleRemoveTargetById=920120;FILES"