check / check (push) In progress
Each app's fixes are one .conf file and one entry in apps. They apply only while Inspect has set the app's transaction variable, such as tx.app_gitea. SWW_APPS names each hostname's apps. A hostname gets only its apps' fixes; while SWW_APPS is unset, every hostname gets every app's fixes. A hostname in SWW_APPS that is not a DNS name, such as *.example.com, stops the start. Unset, SWW_APPS is logged at start as null; set empty, as "". Model: opus-5-5
94 lines
5.9 KiB
Plaintext
94 lines
5.9 KiB
Plaintext
# Vaultwarden's fixes: 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
|
|
|
|
# Unless SWW_APPS lists vaultwarden for the request's hostname, every rule below
|
|
# is skipped. Inspect sets tx.app_vaultwarden when it does.
|
|
# The skip reaches only phase 1, so a rule of a later phase must check
|
|
# tx.app_vaultwarden itself.
|
|
SecRule &TX:app_vaultwarden "@eq 0" \
|
|
"id:900140,phase:1,pass,nolog,skipAfter:END_VAULTWARDEN"
|
|
|
|
# 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"
|
|
|
|
SecMarker END_VAULTWARDEN
|