Associated Vulnerability
Description
CVE-2024–27630 Reference
Readme
# CVE-2024–27630 Vulnerability Details
## Overview
In Savane v3.12 and prior, a lack of validation on the `file_id` parameter when deleting a file from `/bugs/index.php` leads to an Insecure Direct Object Reference (IDOR) vulnerability that can cause an authenticated administrator of a group with a bug tracker to arbitrarily delete file attachments of any bug tracker, leading to a lack of availability of these files. Since the file IDs increment with each new upload, it is possible to create a script that iteratively deletes all file attachments on the server by `file_id`.
**CWE Classification:** CWE-639: Authorization Bypass Through User-Controlled Key
**Reported By:** Ally Petitt
**Affected Product**: Savane
**Affected Versions**: 3.12 and prior
## Technical Details
The function responsible for deleting file attachments on bug trackers is `trackers_data_delete_file()`, which is defined in the code block below.
_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]
);
```
The function begins with a SQL query to verify that the group that the bug ID specified in `item_id` is in the group that the attacker is a part of, known as the `$group_id`. The function fails to check whether the `file_id` is part of the group as well, meaning that as long as the `item_id` cooresponds to a valid bug in the attacker's group, the attacker can modify the `file_id` to point to any file within the upload directory `/var/lib/savane/trackers_attachments`.
Additionally, this function is only reachable for bug tracker admins.
_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;
```
## Validation Steps
These steps demonstrate deleting one file that is unauthorized, however, note that an attacker could automate the deletion of all files by their ID since they are predictable.
1. Have an account that is an admin of a group with a bugtracker (attacker account).
2. With a separate user account (victim), upload a file attachment in a bug report to a group that the attacker is not an admin of. A sample of the subsequent upload directory is as follows where the file `40231` was uploaded by the victim:
```
root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226 40227 40230 40231
```
3. Visit the homepage of the group that the attacker is an admin of. Then, visit Bugs > Browse and note a valid Item ID on the leftmost column of the table. This ID will be used in the next step.
4. As the attacker, make a get request to the path /bugs/index.php?func=delete_file&item_id=<ATTACKER_ITEM_ID>&item_file_id=<FILE_ID_TO_DELETE>.
In my case, this looks like http://172.17.0.2:7890/bugs/index.php?func=delete_file&item_id=50697&item_file_id=40231.
5. Verify that the victim’s file (from a group the attacker doesn’t have privileges on) has been deleted. For example:
```
root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226 40227 40230
```
## Mitigation
Upgrade to Savane version 3.13 or higher. The patch can be found [here](https://git.savannah.nongnu.org/cgit/administration/savane.git/commit/?h=i18n&id=39180aea8f38425035b4d1e73819b58007ac6e83).
File Snapshot
[4.0K] /data/pocs/4e746c6b80655c9ff080b9770c7d35e99d7ebeb1
└── [4.2K] README.md
0 directories, 1 file
Remarks
1. It is advised to access via the original source first.
2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.