CVE-2022-45962 Postauth SQLI

Authenticated SQL Injection in openSIS classic prior to 9.0.

OpenSIS

openSIS is a commercial grade, secure, scalable & intuitive Student Information System, School Management Software from OS4ED. Has all functionalities to run single or multiple institutions in one installation. Web based, php code, MySQL database.

Maintained by OS4ED, openSIS is advertised as an open source Student Information System and comes in two versions: Community and Pro. The source code is available on GitHub here.

Vulnerability Analysis

During a code review of the application I noticed the following lines in CalendarModal.php:

$_REQUEST['event_id'] = mysqli_real_escape_string($connection,optional_param('event_id', '', PARAM_DATA));
if (($_REQUEST['event_id'] || !isset($_REQUEST['event_id'])) && !isset($_REQUEST[assignment_id])) {
    // ...
} else {
    $RET = DBGet(DBQuery('SELECT TITLE,STAFF_ID,DATE_FORMAT(DUE_DATE,\'%d-%b-%y\') AS SCHOOL_DATE,ASSIGNED_DATE,DUE_DATE,DESCRIPTION FROM gradebook_assignments WHERE ASSIGNMENT_ID=\'' . $_REQUEST[assignment_id] . '\''));
    //...
}

As we can see in the first line, openSIS developers sanitized the event_id paramater in order to prevent SQL injection in the first if branch. However, should this parameter be empty, there's another one being used to build a different query in the else branch.

The query can be reduced to this format:

DBGet(DBQuery('SELECT TITLE,... 
    FROM gradebook_assignments 
    WHERE ASSIGNMENT_ID=\'' . $_REQUEST[assignment_id] . '\'
    '));

Apparently, the request parameter assignment_id is concatenated to the condition of a SELECT statement used to retrieve some information from the database.

Since this site is accessible only by authenticated users, an adversary would need a valid set of credentials. Beware that this also includes any student account.

Proof of Concept

Knowing the injectable query, we can craft a specific payload for exploitation:

' // end the condition
UNION SELECT // use union based SQLI to insert arbitrary values in the response
"SQLI CONFIRMED", // our extraction point (read from the database here)
"","","","","" // empty strings for the remaining columns
-- - // commenting out the rest of the query

Impact

Successful exploitation may lead to a full database information disclosure. The database contains PII of both students and teachers as well as grades, settings and the passwords of all users.

Self assigned CVSS score: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N with a base score of 6.5.

Remediation

After contacting the vendor, the vulnerability was soon acknowledged and has now been addressed in the latest release. The fix can be found in this commit: 81799fd.

$_REQUEST['assignment_id'] = sqlSecurityFilter($_REQUEST['assignment_id']);

The parameter is now passed to a filter that includes mysqli_real_escape_string before being used in the query. Although best practices would dictate the use of parameterized queries, the injection should now no longer be possible.

Last updated