Skip to content

The migration re-envelope route lets a stolen session overwrite emergency envelopes #801

Description

@rjzondervan

Code reading on 28 September 2026 at 124849b (development). Unverified: not checked live. Found in the development → beta security review. This is new in the delta: the route does not exist on beta.

What happens

POST /api/v1/migrations/{id}/emergency-contacts/{contactId} (MigrationController::reEnvelopeEmergencyContact, about line 514) is #[NoAdminRequired] only and has no vault-key proof. EmergencyEnvelopeInvalidationService::reEnvelopeForRotation() checks four things: the migration is the caller's, the contact is on the old suite, the migration is in_progress, and the envelope is well-formed JSON sealed to the grantee's active suite id. It cannot tell a real envelope from garbage.

While any migration is open, which is possible for a long time because migrations can be resumed, someone with only the session can overwrite every emergency contact's envelope with garbage. The contact stays granted and the audit log reads normally, but break-glass can no longer work. Once one contact has been re-enveloped, abort refuses as well, because countCommitted counts contacts.

This is a sibling of DELETE /emergency-access/contacts/{id}. The delta proof-gated that route precisely so that a session alone cannot destroy an envelope.

Proposed fix

Add #[VaultKeyProofRequired] to reEnvelopeEmergencyContact. Make the migration's old suite the proof subject, and bind the proof to the contact id and the envelope. Add the route to VaultKeyProofAttributesTest.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions