Vulnérabilités multiples dans Agora Project
- Produit
- Agora Project
- Sévérité
- High
- Versions affectées
- ≤ v25.6.4
- Version corrigée
- v25.10
Introduction
Agora Project est une plateforme collaborative open-source conçue pour faciliter le stockage partagé de fichiers, la prise de notes, la gestion de tâches, les calendriers et d'autres fonctionnalités collaboratives destinées aux équipes et aux organisations.
Vulnérabilités
Plusieurs vulnérabilités de sécurité ont été identifiées dans Agora Project, affectant la version 25.6.4. Elles permettent la divulgation de fichiers sans authentification et, une fois authentifié (ou en mode invité si celui-ci est activé), l'exécution de code arbitraire via des mécanismes de traitement de fichiers non sécurisés. De plus, une vulnérabilité de type cross-site scripting (XSS) a été identifiée dans la logique de gestion des erreurs.
Prises dans leur ensemble, ces vulnérabilités peuvent permettre à des attaquants de lire des fichiers sensibles, de téléverser et d'exécuter des payloads malveillants, et d'exécuter du JavaScript arbitraire dans le navigateur des utilisateurs.
Chronologie
| Date | Description |
|---|---|
| 19/08/2025 | Signalement des vulnérabilités |
| 20/08/2025 | Réponse de l'éditeur |
| 02/10/2025 | Publication d'un correctif |
| 06/01/2026 | Réservation des identifiants CVE |
Détails techniques
Lecture de fichiers sans authentification / CVE-2025-67076
Sous certaines conditions, un attaquant non authentifié peut lire des fichiers du système via le contrôleur misc et l'action ExternalGetFile.
/********************************************************************************************************
* FICHIER JOINT : DOWNLOAD D'UN FICHIER ("nameMd5" : cf. "actionExternalGetFile()")
********************************************************************************************************/
public static function actionAttachedFileDownload()
{
$curFile=MdlObject::attachedFileInfos(Req::param("_id"));
$isFile = is_file($curFile["path"]);
$md1 = md5($curFile["name"]);
$md2 = Req::param("nameMd5");
if(is_file($curFile["path"]) && ($curFile["containerObj"]->readRight() || md5($curFile["name"])==Req::param("nameMd5")))
{File::download($curFile["name"],$curFile["path"]);}
}
public static function attachedFileInfos($file)
{
if(!empty($file)){
if(is_numeric($file)) {$file=Db::getLine("SELECT * FROM ap_objectAttachedFile WHERE _id=".(int)$file);} //Si besoin, récupère les infos en bdd
$file["path"]=PATH_OBJECT_ATTACHMENT.$file["_id"].".".File::extension($file["name"]); //Path/chemin réel du fichier
[...]
return $file;
}
}
À noter que le paramètre GET _id peut être un tableau contenant des données arbitraires. En conséquence, la vérification MD5 perd tout son sens, puisque nous contrôlons les deux valeurs comparées.
Le chemin du fichier téléchargé est lui aussi construit à partir de données que nous contrôlons au sein de ce tableau ; la seule contrainte restante est le point ajouté, qui empêche de lire des fichiers dépourvus d'extension.
Le payload final ressemble à ceci :
/index.php?ctrl=misc&launchDownload=true&typeId=file-&action=ExternalGetFile&nameMd5=<@md5>test<@md5>&_id[name]=test&_id[_id]=../config.inc&_id[objectType]=file&_id[_idObject]=1
Cette vulnérabilité permet d'accéder aux fichiers disposant d'une extension, ce qui peut inclure des fichiers de configuration, des données exportées ou d'autres ressources sensibles selon la configuration du serveur et l'emplacement des fichiers.
Blacklist insuffisante des types de fichiers dangereux / CVE-2025-67077
Cette vulnérabilité peut être exploitée en tant qu'utilisateur authentifié ou en tant qu'invité si l'option est activée. La vérification du type et de l'extension des fichiers n'est pas assez restrictive.
public static function uploadControl($tmpFile, $tmpDatasFolderSize=null)
{
if($tmpFile["error"]==0 && is_file($tmpFile["tmp_name"])){
[...]
$isForbiddenMimeType=preg_match("/(php|javascript|shell|binary|executable|msdownload|debian)/i", finfo_file($finfo,$tmpFile["tmp_name"]));
if(self::isType("forbiddenExt",$tmpFile["name"]) || $isForbiddenMimeType==true) {
Ctrl::notify(Txt::trad("NOTIF_fileVersionForbidden")." : ".$tmpFile["name"]);
return false;
}
elseif(is_uploaded_file($tmpFile["tmp_name"])==false && Req::param("tmpFolderName")==false) {
Ctrl::notify("NOTIF_fileOrFolderAccess");
return false;
}
else {
return true;
}
}
}
La vérification de l'extension repose uniquement sur une blacklist ; il est possible de téléverser un fichier « .phar » qui sera exécuté selon la configuration du serveur web.
En utilisant le contrôleur file et l'action UploadTmpFile, il est possible de choisir le répertoire dans lequel le fichier sera téléversé et donc de remonter jusqu'au webroot.
Cela nous donne l'exécution de commandes et la compromission du serveur.
Exécution de code via téléversement de fichier et Imagick / CVE-2025-67079
La bibliothèque Imagick prend en charge le MSL (Magick Scripting Language), qui permet de lire et d'écrire des fichiers. Il est possible de téléverser un faux PDF : la fonctionnalité de génération de vignettes utilisera Imagick pour lire le PDF, qui sera alors interprété comme du MSL et conduira à l'exécution de code PHP.
Pour empêcher ImageMagick d'interpréter le MSL (Magick Scripting Language), il faut le désactiver explicitement dans le fichier de configuration policy.xml. Cela se fait en ajoutant une règle de politique qui refuse tous les droits au coder MSL.
Par exemple, insérer <policy domain="coder" rights="none" pattern="MSL"/> à l'intérieur de la section <policymap> garantit que toute tentative de chargement ou d'exécution de fichiers MSL sera bloquée au niveau d'ImageMagick. C'est la manière recommandée et la plus fiable pour atténuer les risques de sécurité liés au MSL.
Cross-Site Scripting (XSS) / CVE-2025-67078
Le paramètre notify du contrôleur file utilisé pour afficher les erreurs n'est pas correctement échappé, ce qui permet d'injecter du JavaScript dans le navigateur d'un utilisateur piégé.
Ressources
Continuer la lecture
Parlez-nous de votre projet.
Discutons ensemble de vos besoins et attentes pour vous proposer un service sur mesure.

