Priority 70 sits after RejectListener (77) and before LoginListener (66), and both bounds are load-bearing: - After 77 so a rate-limited IP never reaches a ceremony. Passkeys cannot be used to sidestep a lockout (D3), which is the point of the reviewer's third clarification. - Before 66 because LoginListener treats any POST to the auth subdomain as a login attempt. A ceremony finish body has no username/totp, so Payload::load() returns null and the request would be scored as a failed login, burning a rate-limit token for every legitimate passkey login. Verified in the live container rather than assumed: debug:event-dispatcher confirms 77 -> 70 -> 66. Other properties asserted by tests: every header-bearing request gets a JSON response so fetch() callers never receive HTML; registration identity comes from the live session, never the request body; a failed ceremony is indistinguishable from a wrong TOTP code and spends the same shared budget; and begin is bounded by a separate resource guard that deliberately does not consume failure budget. The listener also marks its responses so SecurityHeadersListener can apply no-store: these are the only browser-facing 2xx this application produces, since the auth subdomain has no forward_auth in front of it. CSP gains publickey-credentials-get/-create only when passkeys are available, so the unavailable case stays byte-identical to before.
41 lines
1.0 KiB
Bash
41 lines
1.0 KiB
Bash
APP_ENV=test
|
|
APP_DEBUG=0
|
|
APP_SECRET=test_secret_key_change_me
|
|
# fixed TOTP secret (JBSWY3DPEHPK3PXP) so functional tests can compute valid codes
|
|
TOTP_URI='otpauth://totp/Test-TOTP?secret=JBSWY3DPEHPK3PXP'
|
|
COOKIE_TTL=2592000
|
|
SUBDOMAIN_REDIRECT=0
|
|
AUTH_SUBDOMAIN=''
|
|
IP_TTL=0
|
|
TEAPOT=1
|
|
BURST_COUNT=10
|
|
BURST_TIME=30
|
|
UPPER_COUNT=100
|
|
UPPER_TIME=3600
|
|
PASSKEY_ENABLED=0
|
|
PASSKEY_RP_NAME=''
|
|
PASSKEY_USER_VERIFICATION='required'
|
|
PASSKEY_TIMEOUT=60000
|
|
PASSKEY_BUTTON_NAME='Sign in with a passkey'
|
|
PASSKEY_REGISTER_NAME='Register this device as a passkey'
|
|
PASSKEY_BEGIN_BURST_COUNT=30
|
|
PASSKEY_BEGIN_BURST_TIME=60
|
|
PUBLIC_PATHS=''
|
|
PUBLIC_BURST_COUNT=100
|
|
PUBLIC_BURST_TIME=60
|
|
PUBLIC_UPPER_COUNT=500
|
|
PUBLIC_UPPER_TIME=3600
|
|
TITLE='Pre-Authentication System'
|
|
BG_COLOR='#029386'
|
|
FG_COLOR='#ffffff'
|
|
ERROR_COLOR='#ffb16d'
|
|
ID_NAME='Session ID'
|
|
TOKEN_NAME='Authentication Token'
|
|
SUBMIT_NAME='Submit'
|
|
ERROR_MESSAGE='Unsuccessful login attempt'
|
|
TEAPOT_TITLE="I'm a teapot"
|
|
TEAPOT_MESSAGE='I refuse to brew coffee'
|
|
TOO_MANY_TITLE='Too many requests'
|
|
TOO_MANY_MESSAGE='Try again later'
|
|
SHELL_VERBOSITY=0
|