{"items":[{"id":"NVI-00002496","kind":"vulnerability","title":"Grav: 2FA Bypass via 'login.regenerate2FASecret' - Secret Rotation During Pending Challenge","revision":1,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected."],"lifecycle":"active","identifiers":["GHSA-7mgc-c7pq-3rr3"],"plain_summary":"OSV carries this publisher advisory for getgrav/grav. This is an aggregated source copy; consult the original publisher and compare update dates.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"The original advisory lists fixed boundaries 2.0.4 for getgrav/grav. Confirm the publisher’s latest guidance.","source_ids":["sr-1af926a3f199ffd57e9865e737ac18b1"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-1af926a3f199ffd57e9865e737ac18b1","url":"https://github.com/advisories/GHSA-7mgc-c7pq-3rr3","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-7mgc-c7pq-3rr3","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:41:59.951Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-1af926a3f199ffd57e9865e737ac18b1"],"technology":"getgrav/grav","known_exclusions":[],"conditions_summary":"### Summary\nWhen 2FA is enabled on an account, submitting correct credentials authenticates the user but leaves them unauthorized pending TOTP verification. During this pending-challenge window, the `login.regenerate2FASecret` task which requires only `$user->exists()`, not `$user->authorized`  can be called without a CSRF nonce. It overwrites the victim's `twofa_secret` on disk with an attacker-chosen value, returns the new secret in the JSON response, and the attacker computes a valid TOTP code to complete the 2FA flow. The second factor is **reduced to password-only**. The exploit was confirmed live after enabling 2FA to a user.\n\n### Details\nFour code locations in login plugin v3.8.10 enable the chain:\n\n**1. Session user set even with 2FA pending**  \n`user/plugins/login/login.php` - `userLogin()` assigns `$session->user = $user` before TOTP verification completes. This makes `$this->grav['user']` point to the victim in the pending-challenge window.\n\n**2. `taskRegenerate2FASecret` - no authorization check**  \n`user/plugins/login/classes/Controller.php`\n\n```php\npublic function taskRegenerate2FASecret()\n{\n    $user = $this->grav['user'];\n    if ($user->exists()) {                  ","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 2.0.4"]}],"null_published_at":"2026-10-31T22:00:33.892Z","source_updated_at":"2026-09-02T22:15:05.405Z","source_disclosed_at":"2026-09-02T22:01:25.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"First indexed by Null; source disclosure date is shown separately.","null_first_observed_at":"2026-10-31T21:41:59.951Z"}],"next_cursor":null,"snapshot_revision":"42594"}