VYPR
High severityNVD Advisory· Published Jun 11, 2026· Updated Jun 11, 2026

CVE-2026-8406

CVE-2026-8406

Description

openSIS Classic 9.3 messaging module IDOR allows authenticated users to read other users' sent messages and attachments.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

openSIS Classic 9.3 messaging module IDOR allows authenticated users to read other users' sent messages and attachments.

Vulnerability

openSIS Classic 9.3 contains an insecure direct object reference (IDOR) vulnerability in the messaging module. The modules/messaging/SentMail.php script retrieves sent-message details using a client-controlled mail_id parameter without verifying that the message belongs to the current authenticated user. The sent-mail listing correctly filters by owner, but the body retrieval branch (lines 60–67) queries msg_outbox solely by mail_id, allowing any authenticated user with access to the messaging module (admin, teacher, parent, student profiles) to view messages sent by other users. Additionally, DownloadWindow.php downloads attachments from user_file_upload by down_id without ownership checks, exposing attachments referenced in vulnerable messages [1]. The vulnerability affects openSIS Classic version 9.3 [3].

Exploitation

An attacker must be authenticated and have access to the messaging module. The attacker can enumerate mail_id values (auto-incrementing integers) by sending requests to SentMail.php?modfunc=body&mail_id=. The server returns the message body, subject, recipients, and timestamps without verifying ownership. For attachments, once a vulnerable message is retrieved, the page includes download links that can be used directly without further authorization checks [1]. The attack requires no special privileges beyond standard user authentication.

Impact

Successful exploitation allows an authenticated attacker to read sent messages and download attachments belonging to other users, including administrative users. This can lead to disclosure of sensitive information such as internal communications, student data, or system credentials. The confidentiality of the messaging system is compromised, and the scope of information leakage depends on the messages stored in the system [1].

Mitigation

The vulnerability is fixed in commit c45d431 [2], which adds ownership validation by joining login_authentication and checking from_user, user_id, and profile_id in the query. The fix also applies sqlSecurityFilter to the mail_id parameter. Users should update to a version that includes this commit. No workaround is documented; the only mitigation is to apply the patch or upgrade to a patched release [2][3].

AI Insight generated on Jun 11, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Patches

1
c45d43146167

Commit regarding security fixes

https://github.com/os4ed/opensis-classicRaj MookherjeeJun 8, 2026via nvd-ref
2 files changed · +29 6
  • DownloadWindow.php+18 4 modified
    @@ -31,6 +31,10 @@
     include 'Data.php';
     
     // Prevent Directory Traversal by sanitizing filename parameters
    + if (User('PROFILE') == 'student')
    +    $user_id = UserStudentID();
    +    else
    +    $user_id = UserID();
     function sanitize_filename($filename) {
         // Fully decode URL encoding to handle double/triple encoding attacks (e.g., %252e%252e%252f)
         // Loop until no more decoding occurs
    @@ -66,10 +70,20 @@ function sanitize_filename($filename) {
     
     if(isset($_REQUEST['down_id']) && $_REQUEST['down_id']!='')
     {
    -    if (isset($_REQUEST['down_id']) && $_REQUEST['down_id'] != '')
    -        $downfile_info = DBGet(DBQuery('SELECT * FROM user_file_upload WHERE download_id=\'' . $_REQUEST['down_id'] . '\''));
    -    else
    -        $downfile_info = DBGet(DBQuery('SELECT * FROM user_file_upload WHERE id=\'' . $_REQUEST['down_id'] . '\''));
    +    if (isset($_REQUEST['down_id']) && $_REQUEST['down_id'] != ''){
    +        $downfile_info = 'SELECT * FROM user_file_upload WHERE download_id=\'' . $_REQUEST['down_id'] . '\'';
    +    if(User('PROFILE')!='admin'){
    +        $downfile_info .= ' AND user_id='.$user_id.'';
    +    }
    +    $downfile_info = DBGet(DBQuery($downfile_info));
    +    }
    +    else{
    +        $downfile_info = 'SELECT * FROM user_file_upload WHERE id=\'' . $_REQUEST['down_id'] . '\'';
    +        if(User('PROFILE')!='admin'){
    +        $downfile_info .= ' AND user_id='.$user_id.'';
    +    }
    +    $downfile_info = DBGet(DBQuery($downfile_info));
    +    }
         header("Cache-Control: public");
         header("Pragma: ");
         header("Expires: 0"); 
    
  • modules/messaging/SentMail.php+11 2 modified
    @@ -58,12 +58,21 @@
         }
     }
     if (isset($_REQUEST['modfunc']) && $_REQUEST['modfunc'] == 'body') {
    +    if (User('PROFILE') == 'student')
    +    $user_id = UserStudentID();
    +    else
    +    $user_id = UserID();
    +
    +    $userName = User('USERNAME');
         //PopTable('header', _messageDetails);
         echo '<div class="panel panel-default">';
         echo '<div class="panel-body">';
     
    -    $mail_id = $_REQUEST['mail_id'];
    -    $mail_body = "select mail_body,mail_Subject,to_user,to_cc,to_bcc,mail_datetime,from_user,mail_attachment,to_grpName from msg_outbox where mail_id='$mail_id'";
    +    // $mail_id = $_REQUEST['mail_id'];
    +    // $mail_body = "select mail_body,mail_Subject,to_user,to_cc,to_bcc,mail_datetime,from_user,mail_attachment,to_grpName from msg_outbox where mail_id='$mail_id'";
    +    // $mail_body_info = DBGet(DBQuery($mail_body));
    +    $mail_id = sqlSecurityFilter($_REQUEST['mail_id']);
    +    $mail_body = "select mail_body,mail_Subject,to_user,to_cc,to_bcc,mail_datetime,from_user,mail_attachment,to_grpName from msg_outbox  JOIN login_authentication lg ON msg_outbox.from_user = lg.username where msg_outbox.mail_id=$mail_id AND from_user='$userName' AND lg.user_id = " . $user_id . " AND lg.profile_id = " .User('PROFILE_ID') . " AND istrash is NULL order by($mail_id) desc";
         $mail_body_info = DBGet(DBQuery($mail_body));
     
         foreach ($mail_body_info as $k => $v) {
    

Vulnerability mechanics

Root cause

"Missing authorization check in the sent-message detail query allows any authenticated user to read arbitrary messages by supplying a sequential mail_id."

Attack vector

An authenticated attacker with access to the messaging module can enumerate sequential `mail_id` values by requesting `modules/messaging/SentMail.php?modfunc=body&mail_id=N` [ref_id=1]. The original query selected from `msg_outbox` without joining on the sender's username, user ID, or profile ID, so any existing message is returned regardless of ownership [ref_id=2]. If the retrieved message contains an attachment, the attacker can then download it via `DownloadWindow.php` by supplying the exposed `down_id` parameter, as that endpoint also lacked an ownership check [ref_id=1].

Affected code

The vulnerability resides in `modules/messaging/SentMail.php` (lines 60-67) where the sent-message body query did not filter by the authenticated user's identity, and in `DownloadWindow.php` (lines 67-100) where file downloads were not scoped to the owner's user_id [ref_id=1]. The patch modifies both files to add authorization checks [patch_id=5616579].

What the fix does

The patch rewrites the SQL query in `SentMail.php` to JOIN `msg_outbox` with `login_authentication` and adds `AND from_user='$userName' AND lg.user_id = $user_id AND lg.profile_id = ...` [patch_id=5616579]. This ensures only messages sent by the currently authenticated user are returned. In `DownloadWindow.php`, the patch appends `AND user_id=$user_id` to the file query for non-admin profiles, preventing unauthorized attachment downloads [patch_id=5616579]. The `mail_id` parameter is also sanitized via `sqlSecurityFilter()` to mitigate SQL injection [ref_id=2].

Preconditions

  • configopenSIS Classic 9.3 instance with the messaging module enabled
  • authAny valid authenticated user account that can access modules/messaging/SentMail.php
  • inputAt least one sent message must exist in the msg_outbox table

Generated on Jun 11, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.