# 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="/files/JHWXUztmBG8VKq3eC9mf" 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ccat.gitbook.io/cyber-sec/cve/cve-2022-45962-postauth-sqli.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
