AI Pentesting

CVE-2026-71504: Mass Assignment Bug Resets Admin Password

Amartya | CodeAnt AI Code Review Platform
Sonali Sood

Founding GTM, CodeAnt AI

CVSS 8.3 · Mass assignment (CWE-915) · Fixed in Dolibarr 24.0.0

The teller at the front desk won't touch the CEO's password without the right authorization. The clerk at the membership window never learned to ask, and happens to sit in front of the exact same filing cabinet.

The attack in six steps

  1. The front door says no: Ask the account interface to change the admin's password and it refuses. (403 Forbidden)

  2. Send the identical change to the membership desk: A completely different window into the same data. (this is the break)

  3. It checks only one thing: can you add members?: A routine permission that has nothing to do with login accounts.

  4. It accepts every field you sent: Including two that quietly belong to the linked account: the target and the new password.

  5. Point them at the administrator: The admin's stored password is overwritten with one you chose. (200 OK)

  6. Log in as admin with your password: Same instance, same key, opposite answer. → full takeover.

Every serious application treats one permission as sacred: who is allowed to change a password. Get that wrong and every other control, every record, every permission structure sits downstream of a single mistake.

Dolibarr's own account-management screen gets this right. Ask it to change the administrator's password without holding the right to manage credentials, and it refuses outright.

What we found is the same exact request, same instance, same API key, same target account, getting a yes simply because it was submitted through a different screen.

Dolibarr runs the back office for plenty of small clubs, associations and companies, and alongside its login accounts it ships a separate feature for managing members, the people who belong to the organization. Different feature, different screen, different permission. Whoever staffs the membership desk is trusted to add and edit member records all day. That was supposed to be the entire extent of what they could touch.

The bug is that this membership screen quietly holds a spare key to the login accounts sitting right next to it, and it is a textbook mass assignment vulnerability: a write endpoint that accepts more fields than it should, because nobody drew a hard line around what a caller is allowed to set.

Two doors into the same room

The rule we applied over and over in this security research is simple: when one part of an app guards something, go and find every other part that can touch the same thing, and check the guard is there too. Applications grow in layers, and the second door into a room is the one that gets forgotten.

Dolibarr's account-management screen treats a password with the respect it deserves. Before it will change one, it checks that the caller actually holds the specific right to manage credentials. A membership key does not, so through that door the answer is a clean refusal.

The members screen is a different door into a database that, it turns out, overlaps. A member record can be linked to a login account. And when you create or edit a member, the members screen does something careless: it takes every field you sent it and writes it onto the record, no questions asked. It checks one thing at the entrance, "are you allowed to manage members?", and then trusts everything that follows.

From an application security perspective, this is the dangerous shape of a mass-assignment vulnerability: a legitimate write endpoint accepts fields that belong to a more privileged part of the application's data model.

The two fields that don't belong

Buried in that pile of accepted fields are two that were never really member fields at all: one that says which login account this member is attached to, and one that says what that account's password should be.

So the attacker fills in a member form, points the "attached account" field at the administrator, sets the "password" field to a string of their choosing, and posts it to the membership desk. The desk checks that the caller can manage members, they can, and then dutifully writes the new password onto the linked account. The linked account is the administrator.

The same password change the front door refused a moment ago is now done, through a window that only ever asked whether you could file paperwork for a club.

What it costs

The instant that write lands, the real administrator is locked out. Their old password simply stops working. The attacker logs straight in with the password they picked. No cracking, no stolen session, no clever timing. One ordinary request from an account that holds nothing but membership permissions, and the whole system changes hands.

There is one soft edge worth being precise about. If a second administrator already exists, recovery is easy. If not, getting back in means an out-of-band reset from the database or the command line, which is why the availability impact is scored as a disruption rather than total destruction. Confidentiality and integrity, though, are at the top of the scale, because by this point the attacker owns everything.

And the permission that makes it all possible is one an administrator hands out without a second thought. "You can manage our members" sounds harmless. It is exactly the access you would give a volunteer registrar at a club.

Dolibarr even lists Members and Users as separate, unrelated modules, so nobody granting the one imagines they are also granting the other. A leaked membership key, a compromised registrar, an over-trusted volunteer, any of them is now a path to full control.

What actually closes this

Dolibarr already had the right instinct built into its account-management screen: refuse credential fields outright, and demand the password permission before touching one. The fix in 24.0.0 brings the members screen under that same discipline.

Sensitive fields get rejected before they are ever written, the password permission is now required, and the quiet sync onto a linked account no longer fires by default.

The lesson outlives this one screen. An endpoint should never assume that every field a caller sends is a field they are entitled to set. The durable fix is a short, explicit allowlist of fields each screen accepts, not a scramble to patch each dangerous field after someone finds it.

And once one part of a codebase gets a sensitive check right, as Dolibarr's account screen did, the next screen touching that same data inherits the same obligation. Skipping it is not a fresh design decision, it is a shortcut somebody owed themselves and did not take.

This is what makes real API security testing worth the name. A scanner can confirm an endpoint has an authorization check and move on. It will not tell you that check is guarding the wrong field, or that a completely different route reaches the same data with a weaker one.

That gap, between "there's a permission check" and "the permission check actually covers what matters," is where this bug lived, and it is the same gap behind the password hash exposure we found in Dolibarr's members API elsewhere in this series.

Confirming it takes someone chaining the request end to end, not just reading the route table. This is privilege escalation in its plainest form: a permission meant for one narrow task, quietly usable for a much bigger one.

The fix

Upgrade to Dolibarr 24.0.0. Curious where your own app quietly disagrees with itself the same way? Start with a free CodeAnt pentest.

Back to all nine findings in the Dolibarr research series

FAQs

Start Your 14-Day Free Trial

AI code reviews, security and quality trusted by modern engineering teams.

Table of Content
No headings found on page
Ship clean & secure code faster

Get Pentest Report

NO CC REQUIRED