
Référence CVE-2024–27630
Dans Savane v3.12 et versions antérieures, l'absence de validation du paramètre file_id lors de la suppression d'un fichier depuis /bugs/index.php entraîne une vulnérabilité de référence directe à un objet (IDOR) qui permet à un administrateur authentifié d'un groupe disposant d'un suivi de bogues de supprimer arbitrairement les pièces jointes de n'importe quel suivi de bogues, entraînant une indisponibilité de ces fichiers. Étant donné que les identifiants de fichiers s'incrémentent à chaque nouvel envoi, il est possible de créer un script qui supprime de manière itérative toutes les pièces jointes du serveur par file_id.
Classification CWE : CWE-639 : Contournement d'autorisation via une clé contrôlée par l'utilisateur
Signalé par : Ally Petitt
Produit concerné : Savane
Versions concernées : 3.12 et versions antérieures
La fonction responsable de la suppression des pièces jointes dans les suivis de bogues est trackers_data_delete_file(), définie dans le bloc de code ci-dessous.
frontend/php/include/trackers/data.php:2417
function trackers_data_delete_file ($group_id, $item_id, $file_id)
{
global $sys_trackers_attachments_dir;
# Make sure the attachment belongs to the group.
$res = db_execute ("
SELECT bug_id from " . ARTIFACT . " WHERE bug_id = ? AND group_id = ?",
[$item_id, $group_id]
);
if (db_numrows ($res) <= 0)
{
# TRANSLATORS: the argument is item id (a number).
$msg = sprintf (
_("Item #%s doesn't belong to project"), $item_id
);
fb ($msg, 1);
return;
}
$result = false;
# Delete the attachment.
if (unlink ("$sys_trackers_attachments_dir/$file_id"))
$result = db_execute ("
DELETE FROM trackers_file WHERE item_id = ? AND file_id = ?",
[$item_id, $file_id]
);
La fonction commence par une requête SQL visant à vérifier que le groupe auquel appartient l'identifiant de bogue spécifié dans item_id correspond au groupe dont l'attaquant fait partie, appelé $group_id. La fonction ne vérifie pas si le file_id fait également partie du groupe, ce qui signifie que tant que item_id correspond à un bogue valide dans le groupe de l'attaquant, celui-ci peut modifier le file_id pour pointer vers n'importe quel fichier du répertoire d'envoi /var/lib/savane/trackers_attachments.
De plus, cette fonction n'est accessible qu'aux administrateurs du suivi de bogues.
frontend/php/bugs/index.php:586
case 'delete_file':
# Remove an attached file.
if ($is_trackeradmin)
{
trackers_data_delete_file($group_id, $item_id, $item_file_id);
# Unset previous settings and return to the item.
$depends_search = $reassign_change_project_search = $add_cc
= $input_file = $changed = $vfl = $details = null;
include '../include/trackers_run/mod.php';
}
else
exit_permission_denied ();
break;
Ces étapes montrent la suppression d'un fichier non autorisé ; cependant, notez qu'un attaquant pourrait automatiser la suppression de tous les fichiers en utilisant leur ID, car ceux-ci sont prévisibles.
40231 a été téléversé par la victime :root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226 40227 40230 40231
Visiter la page d'accueil du groupe dont l'attaquant est administrateur. Ensuite, aller dans Bugs > Parcourir et noter un ID d'élément valide dans la colonne la plus à gauche du tableau. Cet ID sera utilisé à l'étape suivante.
En tant qu'attaquant, envoyer une requête GET au chemin /bugs/index.php?func=delete_file&item_id=<ATTACKER_ITEM_ID>&item_file_id=<FILE_ID_TO_DELETE>.
Dans mon cas, cela ressemble à http://172.17.0.2:7890/bugs/index.php?func=delete_file&item_id=50697&item_file_id=40231.
Vérifier que le fichier de la victime (provenant d'un groupe sur lequel l'attaquant n'a pas de privilèges) a bien été supprimé. Par exemple :
root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226 40227 40230
Mettre à niveau vers Savane version 3.13 ou supérieure. Le correctif est disponible ici.