Lucene search

K
huntr1dayluoE50966CD-9222-46B9-AEDC-1FEB3F2A0B0E
HistoryMay 18, 2023 - 3:34 a.m.

File Path Traversal Vulnerability

2023-05-1803:34:16
1dayluo
www.huntr.dev
7
file path traversal
admin_autoupdate.php
attackers
$_get['archive']
sensitive files
vulnerability
path validation
proof of concept
bug bounty

0.001 Low

EPSS

Percentile

48.7%

Description

in the file admin_autoupdate.php

elseif ($page == 'extract') {
    if (isset($_POST['send']) && $_POST['send'] == 'send') {
        $toExtract = isset($_POST['archive']) ? $_POST['archive'] : null;
        $localArchive = Froxlor::getInstallDir() . '/updates/' . $toExtract;
        $log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Extracting " . $localArchive . " to " . Froxlor::getInstallDir());
        $result = AutoUpdate::extractZip($localArchive);
        if ($result > 0) {
            // error
            Response::redirectTo($filename, [
                'page' => 'error',
                'errno' => $result
            ]);
        }
        // redirect to update-page
        Response::redirectTo('admin_updates.php');
    } else {
        $toExtract = isset($_GET['archive']) ? $_GET['archive'] : null;
        $localArchive = Froxlor::getInstallDir() . '/updates/' . $toExtract;
    }

    if (!file_exists($localArchive)) {
        Response::redirectTo($filename, [
            'page' => 'error',
            'errno' => 7
        ]);
    }

    $text = lng('admin.extractdownloadedzip', [$toExtract]);

    $upd_formfield = [
        'updates' => [
            'title' => lng('update.update'),
            'image' => 'fa-solid fa-download',
            'sections' => [
                'section_autoupd' => [
                    'fields' => [
                        'archive' => ['type' => 'hidden', 'value' => $toExtract]
                    ]
                ]
            ],
            'buttons' => [
                [
                    'class' => 'btn-outline-secondary',
                    'label' => lng('panel.cancel'),
                    'type' => 'reset'
                ],
                [
                    'label' => lng('update.proceed')
                ]
            ]
        ]
    ];

    UI::view('user/form-note.html.twig', [
        'formaction' => $linker->getLink(['section' => 'autoupdate', 'page' => 'extract']),
        'formdata' => $upd_formfield['updates'],
        // alert
        'type' => 'warning',
        'alert_msg' => $text
    ]);
} // display error

This code fails to properly validate file paths in admin_autoupdate.php. Attackers are able to detect if any file exists and extract compressed files by manipulating the $_GET['archive']. This allows detect files like ../../../../../../../etc/passwd and even extract compressed files if exists.It only checks if the path exists, but does not check if it is a sensitive path, resulting in a directory traversal vulnerability.
(The test environment is 2.0.14, but I checked the code in the current main branch and found that the logic for path validation is the same - it does not check if the path is sensitive. )

Proof of Concept

step 1: set enable_webupdate=true

step 2: set page=extract&archive=../../../../../../etc/passwd (example : admin_autoupdate.php?page=extract&archive=…/…/…/…/…/…/…/…/…/…/etc/passwd)

POC video

0.001 Low

EPSS

Percentile

48.7%

Related for E50966CD-9222-46B9-AEDC-1FEB3F2A0B0E