Vulnérabilités multiples dans InvoicePlane
- Produit
- InvoicePlane
- Sévérité
- High
- Versions affectées
- ≤ 1.6.3
- Version corrigée
- 1.6.4
Introduction
InvoicePlane est une application web open source auto-hébergée conçue pour gérer les devis, les factures, les clients et les paiements. Elle est utilisée par les petites entreprises et les indépendants comme solution de facturation.
Vulnérabilités
Plusieurs vulnérabilités de sécurité ont été identifiées dans InvoicePlane et affectent la version « 1.6.3 ». Elles comprennent une lecture de fichiers non authentifiée, une injection SQL authentifiée et un upload arbitraire de fichiers PHP authentifié, susceptible de conduire à une exécution de code à distance (RCE).
Au moment de la découverte, InvoicePlane ne met pas en œuvre de séparation des rôles : le seul rôle utilisateur disponible est le rôle d'administrateur. Si cela limite les scénarios d'élévation de privilèges, l'impact des vulnérabilités authentifiées reste important en raison du niveau d'accès élevé accordé par défaut.
Chronologie
| Date | Description |
|---|---|
| 18/08/2025 | Signalement des vulnérabilités via le projet GitHub |
| 21/08/2025 | Réponse de l'éditeur et début des corrections |
| 01/12/2025 | La v1.6.4-beta-1 corrige les vulnérabilités |
| 06/01/2026 | Réservation des identifiants CVE |
Détails techniques
Lecture de fichiers non authentifiée / CVE-2025-67083
Un attaquant non authentifié peut lire des fichiers présents sur le serveur au moyen d'une vulnérabilité de traversée de répertoire (directory traversal). L'étendue de l'accès aux fichiers dépend de la configuration du serveur web et des permissions du système de fichiers.
L'endpoint vulnérable est le suivant :
/guest/get/get_file/<filename>
public function get_file($filename): void
{
$filename = urldecode($filename);
if ( ! file_exists($this->targetPath . $filename)) {
$ref = isset($_SERVER['HTTP_REFERER']) ? ', Referer:' . $_SERVER['HTTP_REFERER'] : '';
$this->respond_message(404, 'upload_error_file_not_found', $this->targetPath . $filename . $ref);
}
$path_parts = pathinfo($this->targetPath . $filename);
$file_ext = mb_strtolower($path_parts['extension'] ?? '');
$ctype = $this->content_types[$file_ext] ?? $this->ctype_default;
$file_size = filesize($this->targetPath . $filename);
header('Expires: -1');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Type: ' . $ctype);
header('Content-Length: ' . $file_size);
readfile($this->targetPath . $filename);
}
Le paramètre filename est utilisé sans assainissement ni validation appropriés, ce qui permet d'y injecter des séquences de traversée (par exemple ../). Un attaquant peut ainsi accéder à des fichiers arbitraires sur le serveur, sous réserve des restrictions du serveur web.
Cette vulnérabilité peut permettre à des attaquants de lire des fichiers de configuration sensibles, des journaux ou d'autres données applicatives.
Injection SQL authentifiée / CVE-2025-67082
Un utilisateur authentifié peut injecter des commandes SQL arbitraires via des paramètres POST vulnérables de la fonctionnalité de reporting.
Le problème se situe dans le fichier Mdl_reports.php, où les paramètres minQuantity et maxQuantity sont directement intégrés dans une requête SQL sans assainissement approprié ni recours à des requêtes préparées.
$this->db->where('
(
SELECT SUM(amounts.invoice_total) FROM ip_invoice_amounts amounts
WHERE amounts.invoice_id IN
(
SELECT inv.invoice_id FROM ip_invoices inv
WHERE inv.client_id=ip_clients.client_id
AND ' . $this->db->escape($from_date) . ' <= inv.invoice_date_created
AND ' . $this->db->escape($to_date) . ' >= inv.invoice_date_created
AND ' . $minQuantity . ' <=
(
SELECT SUM(amounts2.invoice_total) FROM ip_invoice_amounts amounts2
WHERE amounts2.invoice_id IN
(
SELECT inv2.invoice_id FROM ip_invoices inv2
WHERE inv2.client_id=ip_clients.client_id
AND ' . $this->db->escape($from_date) . ' <= inv2.invoice_date_created
AND ' . $this->db->escape($to_date) . ' >= inv2.invoice_date_created
)
)
)
) <>0');
Ces paramètres n'étant pas traités de manière sûre, un attaquant peut manipuler la requête SQL et potentiellement provoquer :
- La divulgation d'informations sensibles de la base de données
- La modification ou la suppression de données
- Le détournement de fonctionnalités de la base de données selon les permissions
Upload arbitraire de fichiers PHP authentifié / CVE-2025-67084
Un utilisateur authentifié peut téléverser des fichiers PHP arbitraires via la fonctionnalité d'upload de pièces jointes, ce qui conduit à une exécution de code à distance.
Dans le gestionnaire d'upload Upload.php, une vérification du type MIME est partiellement mise en place :
$tempFile = $_FILES['file']['tmp_name'];
if (extension_loaded('fileinfo')) {
$this->validate_mime_type(mime_content_type($tempFile));
}
Cependant, la fonction s'appuie sur un tableau contenant les types de contenu autorisés, dont text/plain. Il est alors possible de téléverser un fichier PHP tout en déclarant un type MIME anodin tel que text/plain.
Une fois téléversés, ces fichiers PHP peuvent être appelés et exécutés par le serveur, ce qui permet à un attaquant d'exécuter du code arbitraire dans le contexte de l'application web.
Ressources
Continuer la lecture
Parlez-nous de votre projet.
Discutons ensemble de vos besoins et attentes pour vous proposer un service sur mesure.

