generated from jric11/baseProject
71 lines
3.8 KiB
Markdown
71 lines
3.8 KiB
Markdown
|
|
# MFA lifecycle repairs — October 20, 2026
|
||
|
|
|
||
|
|
Repairs the two confirmed MFA findings in
|
||
|
|
[the readiness review](MULTI-TENANT-READINESS-2026-10-20.md).
|
||
|
|
|
||
|
|
## Authenticator replacement
|
||
|
|
|
||
|
|
Starting replacement requires the current password and an unused authenticator
|
||
|
|
or recovery code. The existing factor and all remaining recovery codes stay
|
||
|
|
active. A ten-minute replacement grant holds the new secret in the authorized
|
||
|
|
server-side session and binds it to the account version and existing factor.
|
||
|
|
The page offers a QR code, manual setup key and cancellation.
|
||
|
|
|
||
|
|
Confirmation requires the password again and a valid code from the new device.
|
||
|
|
One transaction locks the account and factor, checks authorization, replaces the
|
||
|
|
encrypted secret, generates ten fresh recovery codes, increments the session
|
||
|
|
version and writes the mandatory audit entry. Other sessions and old recovery
|
||
|
|
codes are revoked only when this transaction commits. The confirmation code is
|
||
|
|
recorded as consumed so it cannot immediately be replayed.
|
||
|
|
|
||
|
|
Cancellation, expiration, incorrect credentials and audit failure leave the
|
||
|
|
existing factor intact. Password resets preserve MFA and invalidate the pending
|
||
|
|
session. Competing confirmations cannot both succeed. Signing in clears any
|
||
|
|
previous pending replacement from that session.
|
||
|
|
|
||
|
|
## Password and code verification
|
||
|
|
|
||
|
|
MFA verification checks the current password, active account, session identity
|
||
|
|
and account version under the account lock before consuming an authenticator
|
||
|
|
time step or recovery code. Every mutation follows the account-then-factor lock
|
||
|
|
order, with consumption and mandatory audit committed together. Existing attempt
|
||
|
|
limits continue to apply. The verification API requires the password explicitly.
|
||
|
|
|
||
|
|
## Security notifications
|
||
|
|
|
||
|
|
Email notices use the account address read under the account lock. Events cover
|
||
|
|
initial enrollment, replacement requested, replacement completed and recovery
|
||
|
|
code use. Recovery-authorized replacement sends one combined request/recovery
|
||
|
|
notice. Notices identify the account and UTC time and explain what to do if the
|
||
|
|
activity was unauthorized. They contain no passwords, setup secrets, provisioning
|
||
|
|
links or recovery codes.
|
||
|
|
|
||
|
|
Delivery uses the existing SMTP configuration after the security transaction
|
||
|
|
commits. Failed or rolled-back actions send no success notice. A delivery failure
|
||
|
|
does not undo the security change: it produces a visible warning and a log entry
|
||
|
|
containing the account ID and event type. Delivery is best effort, without a new
|
||
|
|
queue or automatic retry; production SMTP/inbox delivery and failure monitoring
|
||
|
|
still need deployment acceptance.
|
||
|
|
|
||
|
|
## Validation and deployment
|
||
|
|
|
||
|
|
New regressions cover 24 HTTP lifecycle assertions, 24 notification assertions
|
||
|
|
and two concurrent database races. Existing MFA capacity and QR scanning tests
|
||
|
|
were updated for explicit replacement confirmation and password-required
|
||
|
|
verification. The release packaging test requires the notification class.
|
||
|
|
All tests use disposable local databases and generated accounts; notification
|
||
|
|
tests capture messages or deliberately disable SMTP. No real account password,
|
||
|
|
MFA factor or recovery codes are changed, and no test email is sent externally.
|
||
|
|
|
||
|
|
No database migration, encryption-key change or administrator re-enrollment is
|
||
|
|
required. Deploy `classes/MfaSecurityNotifications.php` before the updated
|
||
|
|
`MfaService.php`, `AuthService.php` and `Roster.php`.
|
||
|
|
|
||
|
|
Completed validation: the full suite passed 743 checks and 12 concurrency
|
||
|
|
scenarios. Source validation passed for 65 PHP files, 57 JavaScript files and
|
||
|
|
39 XSL stylesheets. The four application files were deployed to ositsdevels and
|
||
|
|
their hashes verified. A temporary protected runtime check confirmed the
|
||
|
|
password-required verification API, replacement methods, notification class and
|
||
|
|
working server-side encryption key; the probe was removed immediately afterward.
|
||
|
|
No development database records were changed.
|