Full CSRF Bypass in unilogies/bumsys
Reported on
Mar 1st 2023
Description
The intended way to reach functionality in $module/ajax.php is through the /xhr endpoint.
Looking at the following code:
https://github.com/unilogies/bumsys/blob/83bd788c21ce390f62e34ab6755a3e61c106418c/core/route.php#L43-L48
if( ($pageSlug === "xhr" or $pageSlug === "info") and ( !isset($_SERVER["HTTP_X_CSRF_TOKEN"]) or (isset($_SERVER["HTTP_X_CSRF_TOKEN"]) and $_SERVER["HTTP_X_CSRF_TOKEN"] !== $_SESSION["csrf_token"] ) ) ) {
header('HTTP/1.0 403 Forbidden');
die("<strong>Error:</strong> You have no permission to access this server.");
}
We see that if and only if the $pageSlug contains xhr
or info
, the CSRF token is actually checked.
The general routing logic is as follows: when making a GET or POST request to /$module/$action, the file /module/$module/$action is included. Because the ajax.php file is in each module's directory, for example module/accounts/ajax.php
.
We can reach the code in ajax.php directly with the route http://bumsys.local/accounts/ajax
and thus completely bypassing the CSRF check.
PoC
Make a GET request to for example http://bumsys.local/accounts/ajax?page=accountList
to reach ajax.php code without the CSRF token.
Impact
Since this is a complete CSRF bypass, every endpoint is vulnerable to CSRF attacks, this could be leveraged to create a new admin account amongst other things.