CVE-2026-71509 Overview
CVE-2026-71509 is an improper authorization vulnerability [CWE-862] in Dolibarr ERP/CRM versions prior to 24.0.0. The flaw resides in the expense report REST API update endpoint, where the handler applies mass-assignment to request fields without filtering workflow-state properties. Authenticated attackers with expense-creation rights can directly set the fk_statut (approval status) and fk_user_approve (approver identity) fields through the API, bypassing the dedicated approval right entirely. The result is unauthorized self-approval of expense reports and inconsistent audit records because approval timestamps remain unpopulated.
Critical Impact
Authenticated users with minimal privileges can self-approve or close their own expense reports and forge approver identity, breaking segregation-of-duties controls and corrupting financial audit trails.
Affected Products
- Dolibarr ERP/CRM versions prior to 24.0.0
- Deployments exposing the expense report REST API (/api/index.php/expensereports)
- Instances where non-approver users hold expense-creation rights
Discovery Timeline
- 2026-08-24 - CVE-2026-71509 published to NVD
- 2026-08-27 - Last updated in NVD database
Technical Details for CVE-2026-71509
Vulnerability Analysis
The vulnerability is a mass-assignment authorization flaw in the Dolibarr expense report REST API. The PUT handler in htdocs/expensereport/class/api_expensereports.class.php iterates over incoming request fields and assigns each value directly to the corresponding property on the expensereport object. The iteration does not exclude fields that represent workflow state, so any authenticated caller can overwrite the approval status and approver identity fields intended to be managed only by the dedicated approval workflow methods.
An attacker with the standard expense-creation right can submit an update request that sets fk_statut to an approved or closed state and populates fk_user_approve with an arbitrary user ID. The approval workflow methods that would normally validate the caller's dedicated approval right and stamp approval timestamps are never invoked, breaking segregation of duties and leaving forensic gaps in audit records.
Root Cause
The root cause is missing authorization on writable fields [CWE-862]. The API update loop treats workflow-state columns as ordinary editable properties. There is no check that the requester holds the expensereport->approve right before writing to fk_statut or fk_user_approve, and no allowlist restricts which columns clients may modify through the REST update endpoint.
Attack Vector
Exploitation requires network access to the Dolibarr REST API and authenticated credentials with expense-creation rights. The attacker issues an authenticated PUT to the expense report update endpoint and includes fk_statut and fk_user_approve in the JSON body. The server writes those fields to the record, advancing the report to an approved or closed state without invoking the approval workflow.
continue;
}
- $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
+ if ($field == 'array_options' && is_array($value)) {
+ foreach ($value as $index => $val) {
+ $this->expensereport->array_options[$index] = $this->_checkValExtrafieldsForAPI($index, $val, $this->expensereport);
+ }
+ continue;
+ }
+
+ if (!in_array($field, array('fk_statut', 'fk_user_approve'))) { // Exclude properties that must be set by other workflow methods
+ $this->expensereport->$field = $this->_checkValForAPI($field, $value, $this->expensereport);
+ }
Source: Dolibarr commit 9c4eb94. The patch adds an exclusion list so that fk_statut and fk_user_approve cannot be assigned through the generic API update loop and must be modified only by dedicated workflow methods.
Detection Methods for CVE-2026-71509
Indicators of Compromise
- Expense reports whose status transitioned to approved or closed without a corresponding approval timestamp in audit tables.
- REST API PUT requests to /api/index.php/expensereports/{id} containing fk_statut or fk_user_approve in the JSON payload.
- Records where fk_user_approve references a user other than the one authenticated in the originating session token.
- Approval state changes attributed to accounts that do not hold the expensereport->approve right.
Detection Strategies
- Parse web server access logs for PUT requests to the expense report REST endpoint and correlate bodies containing workflow-state fields.
- Run periodic database consistency checks comparing fk_statut, fk_user_approve, and approval timestamps to flag records missing expected metadata.
- Alert on API calls where the authenticated user identifier does not match fk_user_approve written in the same request.
Monitoring Recommendations
- Forward Dolibarr application and web server logs to a centralized log platform and retain full request bodies for the REST API.
- Monitor for privilege inconsistencies between the caller's rights profile and the workflow transitions their requests trigger.
- Track baseline volumes of expense approvals per user and alert on anomalous self-approval patterns.
How to Mitigate CVE-2026-71509
Immediate Actions Required
- Upgrade Dolibarr to version 24.0.0 or later, which contains the fix in commit 9c4eb94.
- Audit historical expense report records for status transitions that lack approval timestamps or that were performed by non-approver users.
- Review and tighten REST API user rights so that only trusted accounts hold expense-creation permissions.
Patch Information
The fix is included in Dolibarr 24.0.0. The commit modifies htdocs/expensereport/class/api_expensereports.class.php to exclude fk_statut and fk_user_approve from generic REST field assignment, forcing those fields through the dedicated approval workflow methods. See the VulnCheck advisory and CodeAnt security research for additional technical detail.
Workarounds
- Disable the expense report REST API endpoint at the web server or reverse proxy layer until the patch is applied.
- Restrict network access to /api/index.php/expensereports to trusted internal IP ranges only.
- Revoke expense-creation rights from any user account that does not require API-driven expense submission.
# Example reverse-proxy block for the vulnerable endpoint (nginx)
location ~ ^/api/index\.php/expensereports {
deny all;
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

