CVE-2026-71511 Overview
CVE-2026-71511 is a sensitive data exposure vulnerability in Dolibarr ERP/CRM versions prior to 24.0.0. The flaw resides in the Members REST API, where the base API serializer and the Members API class fail to strip the pass_indatabase_crypted field from responses. Authenticated attackers holding member-read rights can query individual member or member list endpoints to retrieve bcrypt password verifiers stored for member accounts. Extracted hashes enable offline password cracking against Dolibarr member credentials. The vulnerability is categorized as Insufficiently Protected Credentials [CWE-522].
Critical Impact
Any authenticated API user with member-read permission can harvest bcrypt password hashes for every Dolibarr member and attempt offline cracking to recover cleartext passwords.
Affected Products
- Dolibarr ERP/CRM versions before 24.0.0
- Dolibarr Members REST API (htdocs/api/class/api.class.php)
- Deployments exposing the REST API to authenticated users with member-read scope
Discovery Timeline
- 2026-08-24 - CVE-2026-71511 published to the National Vulnerability Database (NVD)
- 2026-08-26 - Last updated in NVD database
Technical Details for CVE-2026-71511
Vulnerability Analysis
Dolibarr exposes member records through a REST API served from htdocs/api/class/api.class.php. The base API serializer applies an object cleanup routine that unsets sensitive properties before returning JSON. Prior to the fix, the routine removed table_rowid, pass, and pass_indatabase, but omitted pass_indatabase_crypted. The Members API subclass did not filter the field either.
As a result, authenticated callers to the individual member endpoint or the member list endpoint receive the bcrypt verifier alongside standard member data. An attacker with limited API privileges converts read access into a credential harvesting primitive. Recovered passwords can be reused against the Dolibarr web console or any linked identity system where members reuse credentials.
Root Cause
The root cause is an incomplete allow/deny list in the API response sanitizer. The serializer relied on manually enumerated unset() calls for each sensitive field. Adding pass_indatabase_crypted as a stored column without updating the serializer left the crypted verifier reachable through the API. This is a classic case of Insufficiently Protected Credentials [CWE-522] combined with an information disclosure defect in the serialization layer.
Attack Vector
Exploitation requires network access to the Dolibarr API and valid credentials with member-read rights. The attacker authenticates against the REST API, then issues a GET request to /api/index.php/members or /api/index.php/members/{id}. The JSON response includes the pass_indatabase_crypted field containing the bcrypt hash. The attacker feeds the hashes into offline crackers such as hashcat mode 3200 to recover cleartext passwords.
unset($object->table_rowid);
unset($object->pass);
unset($object->pass_indatabase);
+ unset($object->pass_indatabase_crypted);
// Remove linkedObjects. We should already have and keep only linkedObjectsIds that avoid huge responses
unset($object->linkedObjects);
Source: GitHub Commit b1691356. The patch adds a single unset() call for pass_indatabase_crypted in the shared API serializer, ensuring the field is stripped from every API response.
Detection Methods for CVE-2026-71511
Indicators of Compromise
- API responses from /api/index.php/members or /api/index.php/members/{id} containing a pass_indatabase_crypted field in the JSON body.
- High-volume enumeration of member IDs by a single API token or DOLAPIKEY within a short window.
- Unexpected GET requests to the Members API from IP ranges that do not typically consume the Dolibarr REST interface.
Detection Strategies
- Inspect web server access logs for repeated queries to /api/index.php/members paginated with increasing page or sqlfilters parameters.
- Deploy a response-body inspection rule at the reverse proxy or WAF that flags JSON payloads containing the string pass_indatabase_crypted.
- Correlate Dolibarr application logs with authentication events to identify low-privilege API accounts pulling full member lists.
Monitoring Recommendations
- Forward Dolibarr HTTP access logs and PHP error logs to a centralized log platform and alert on Members API access patterns.
- Track the count of distinct member IDs accessed per API key over rolling one-hour windows and alert on spikes.
- Monitor egress traffic from the Dolibarr host for outbound transfers of large JSON payloads following Members API queries.
How to Mitigate CVE-2026-71511
Immediate Actions Required
- Upgrade Dolibarr to version 24.0.0 or later, which includes commit b1691356 that removes pass_indatabase_crypted from API responses.
- Rotate credentials for all Dolibarr members, as any exposed bcrypt hashes must be assumed cracked or crackable offline.
- Revoke and reissue all Dolibarr API keys (DOLAPIKEY) that had member-read permissions before the patch was applied.
- Audit REST API access logs for prior enumeration of the Members endpoints and treat any hits as a credential compromise event.
Patch Information
The fix is delivered in Dolibarr Release 24.0.0. The upstream patch is GitHub Commit b1691356, which adds an unset($object->pass_indatabase_crypted) call in htdocs/api/class/api.class.php. Additional context is available in the Codeant Security Research writeup and the Vulncheck Advisory on Dolibarr.
Workarounds
- Restrict the REST API at the web server or reverse proxy to trusted source networks until the upgrade to 24.0.0 is complete.
- Remove the member-read permission from all API-only users that do not strictly require it.
- Apply the one-line unset() change from commit b1691356 as a temporary hotfix on unpatched deployments.
# Verify the patched line is present in the API serializer
grep -n "pass_indatabase_crypted" htdocs/api/class/api.class.php
# Confirm Dolibarr version is 24.0.0 or later
php -r 'include "htdocs/filefunc.inc.php"; echo DOL_VERSION;'
# Block the vulnerable field at the reverse proxy (nginx example)
# location /api/index.php/members {
# proxy_pass http://dolibarr_backend;
# sub_filter '"pass_indatabase_crypted":"[^"]*",' '';
# sub_filter_types application/json;
# sub_filter_once off;
# }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

