Skip to content

[Critical] Fix admin impersonation escape hatch and admin-to-admin protection #45

@ibourgeois

Description

@ibourgeois

Problem

The admin.impersonation.destroy route sits inside the ['auth', 'can:access-admin'] middleware group. Once an admin impersonates a regular user, the session user is that non-admin. Hitting DELETE /admin/impersonation returns a 403 — the admin is permanently locked in with no way out.

Additionally, ImpersonationController::store() has no guard against:

  • Self-impersonation ($user->id === $request->user()->id)
  • Impersonating another admin

The existing impersonation test (ImpersonationTest.php) masks this bug by calling $this->actingAs($admin) before the DELETE request — bypassing the real session state.

Required Changes

  • Move admin.impersonation.destroy route out of the can:access-admin middleware group into the plain auth group
  • In ImpersonationController::destroy(), replace Gate::authorize('access-admin') with abort_unless($request->session()->has('impersonator_id'), 403)
  • In ImpersonationController::store(), add guards: abort 422 if self-impersonating; abort 422 if target user is an admin
  • Fix ImpersonationTest to test the real session flow (logs in, starts impersonation, then destroys without re-authing)

Files

  • routes/web.php
  • app/Http/Controllers/Admin/ImpersonationController.php
  • tests/Feature/Admin/ImpersonationTest.php

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions