# Laravel Backpack CRUD: Unverified password change in MyAccountController via mass assignment

Backpack CRUD's edit-account-info endpoint mass-assigns any $fillable column including password, letting a session holder reset the victim's password without old_password.

- Payout: Research
- Severity: high
- Program: Backpack CRUD
- Found by: therawdev
- Disclosed: 2026-08-20
- CVE: CVE-2026-54175
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-xpv2-hrfc-hw62
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-xpv2-hrfc-hw62
- Tags: area:web domain:web impact:ato impact:privesc kind:research platform:ghsa sev:high tech:php technique:source-review vuln:access-control vuln:account-takeover vuln:auth-bypass

**Target:** Laravel admin panel account-info endpoint (POST /admin/edit-account-info)
**Root cause:** postAccountInfoForm passes $request->except(['_token']) straight to user()->update(), so every $fillable column (password, email, role_id, etc.) is mass-assigned; AccountInfoRequest::validationData() narrows validation only, not the saved data, bypassing the old_password check enforced by the separate change-password route.
**Steps:**
1. Obtain any authenticated Backpack admin session cookie (XSS, stolen device, shared terminal).
2. Send `POST /admin/edit-account-info` with `_token=<csrf>` and `password=<attacker_value>` (plus name/email as needed).
3. Model's `hashed` cast hashes the plaintext and persists it; no old_password is requested.
4. Log in with the new password to confirm persistent takeover; optionally set `email=<attacker_email>` to enable password-reset pivot.
**How found:** Code reading of MyAccountController: noticed the handler used $request->except(['_token']) instead of validated data, then compared against the separate change-password route that enforces old_password via ChangePasswordRequest::withValidator, and checked the default User model's $fillable to confirm password was assignable.
**Exploitation:** Attacker with a hijacked session submits one POST to the account-info form including a new password field; the hashed cast stores it, converting time-limited session access into permanent account takeover, and the same request can rewrite the auth email column for a reset-flow backup channel.
**Escalation:** On deployments where the admin user model's $fillable includes role_id, is_admin, team_id, email_verified_at or two_factor_secret, the same request mass-assigns those, yielding privilege escalation and 2FA disablement.
**Insight:** When an app has a dedicated sensitive-action endpoint (change-password) with extra verification, grep sibling profile/account-update handlers for raw $request->all()/except() passed to update() — the weaker handler often mass-assigns the same sensitive columns and silently bypasses the hardened path.

