Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-71508

CVE-2026-71508: Dolibarr Privilege Escalation Vulnerability

CVE-2026-71508 is a privilege escalation flaw in Dolibarr that allows attackers with user-write rights to modify payroll data without authorization. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-71508 Overview

CVE-2026-71508 is an improper authorization vulnerability in Dolibarr ERP/CRM versions prior to 24.0.0. The flaw resides in the user REST API update endpoint, which enforces an incomplete credential denylist that omits payroll-related columns. Authenticated attackers holding only user-write rights can modify salary, bonus, hourly rate, daily rate, and weekly hours for any user without holding payroll rights. Modified values propagate into payroll export reports, enabling financial fraud and data integrity attacks against HR and accounting workflows. The weakness is classified as [CWE-862] Missing Authorization.

Critical Impact

Any authenticated user with user-write permissions can silently rewrite payroll data for arbitrary users, corrupting salary reports and enabling downstream financial fraud.

Affected Products

  • Dolibarr ERP/CRM versions prior to 24.0.0
  • Dolibarr REST API user update endpoint (htdocs/user/class/api_users.class.php)
  • Downstream payroll export reporting components consuming user records

Discovery Timeline

  • 2026-08-24 - CVE-2026-71508 published to NVD
  • 2026-08-24 - Last updated in NVD database

Technical Details for CVE-2026-71508

Vulnerability Analysis

The Dolibarr REST API exposes a PUT /users/{id} endpoint that accepts a JSON body of field-value pairs to update user records. The endpoint iterates over the caller-supplied fields and applies them to the underlying User object. To prevent trivial account takeover, the handler enforces a denylist of sensitive credential fields that cannot be modified through the API.

The denylist covered password and API key fields but did not include payroll columns such as salary, salaryextra, thm (hourly rate), tjm (daily rate), and weeklyhours. As a result, the mass-assignment loop applied any payroll field passed in the request body without a permission check against the payroll module. Attackers with the standard user->user->write privilege bypass the payroll authorization boundary entirely.

Root Cause

The root cause is a denylist-based authorization pattern in the API update handler. Denylists fail open whenever the schema grows, and Dolibarr's User object contains payroll fields that were never enumerated as protected. The handler lacks a per-field permission map that would require salaries->write for payroll columns.

Attack Vector

Exploitation requires an authenticated session with user-write rights and network access to the Dolibarr API. The attacker issues a single authenticated PUT request to the user update endpoint with payroll fields in the JSON payload. The server applies the values, and subsequent payroll exports reflect the tampered data.

php
// Vulnerable pattern in htdocs/user/class/api_users.class.php
// Denylist omits payroll fields (salary, thm, tjm, weeklyhours, salaryextra)
foreach ($request_data as $field => $value) {
    if (in_array($field, array('pass_crypted', 'pass_indatabase', 'pass_indatabase_crypted', 'pass_temp', 'api_key'))) {
        // These properties can't be set/modified with API
        throw new RestException(405, 'The property '.$field." can't be set/modified using the APIs");
    }
    $this->useraccount->$field = $value; // payroll columns fall through here
}

Source: GitHub Dolibarr Commit c85d0e8

Detection Methods for CVE-2026-71508

Indicators of Compromise

  • HTTP PUT requests to /api/index.php/users/{id} containing JSON keys salary, salaryextra, thm, tjm, or weeklyhours.
  • Unexplained deltas in the llx_user database table on payroll columns without a corresponding change in the payroll module audit log.
  • Payroll export reports showing salary values that do not reconcile with HR-approved records.
  • API activity from accounts that hold user-write but not salaries->write rights touching payroll fields.

Detection Strategies

  • Enable Dolibarr API access logging and alert on PUT /users/* calls whose bodies contain payroll field names.
  • Diff the salary, thm, tjm, and weeklyhours columns of llx_user against a nightly baseline and flag drift.
  • Correlate API caller identity with the payroll module permission matrix to detect privilege-scope violations.

Monitoring Recommendations

  • Ship webserver and Dolibarr application logs to a centralized data lake with structured parsing for API endpoint, caller, and request body keys.
  • Add continuous monitoring for anomalous editing patterns targeting HR and payroll tables.
  • Review API token issuance and rotate tokens for any account seen touching payroll fields prior to the upgrade.

How to Mitigate CVE-2026-71508

Immediate Actions Required

  • Upgrade Dolibarr to version 24.0.0 or later, which introduces a per-field permission guard for payroll columns.
  • Audit the llx_user table and payroll exports for the period since API access was enabled and reconcile against approved HR records.
  • Restrict issuance of user->user->write API rights to accounts that operationally require them.
  • Rotate API keys for all accounts that could reach the user update endpoint.

Patch Information

The fix is available in the Dolibarr 24.0.0 release. The upstream commit c85d0e8 adds an authorization guard requiring the salary module permission before payroll fields can be modified through the API. See the VulnCheck advisory and the Codeant Security research write-up for additional context.

Workarounds

  • Disable the REST API module in Dolibarr configuration until the upgrade is applied.
  • Restrict access to /api/index.php/users/* at the reverse proxy or WAF layer, blocking PUT requests that contain payroll field keys.
  • Temporarily revoke user-write API rights for non-administrative accounts.
bash
# Example NGINX rule blocking payroll field mass-assignment on the user API
location ~ ^/api/index\.php/users/[0-9]+$ {
    if ($request_method = PUT) {
        access_by_lua_block {
            local body = ngx.req.get_body_data() or ""
            if body:find('"salary"') or body:find('"thm"')
               or body:find('"tjm"') or body:find('"weeklyhours"')
               or body:find('"salaryextra"') then
                ngx.exit(403)
            end
        }
    }
    proxy_pass http://dolibarr_backend;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.