
openSIS Classic 9.3 - Insecure Direct Object Reference in Sent Mail
7.1
High
Discovered by
External researcher
Summary
Full name
openSIS Classic 9.3 - Insecure Direct Object Reference in Sent Mail message retrieval and attachment download
Code name
State
Public
Release date
Affected product
openSIS Classic
Vendor
openSIS
Affected version(s)
9.3
Fixed version(s)
commit (c45d431)
Vulnerability name
Stored cross-site scripting (XSS)
Vulnerability type
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
CVSS v4.0 base score
7.1
Exploit available
Yes
CVE ID(s)
Description
openSIS Classic 9.3 contains an insecure direct object reference vulnerability in the messaging module. Any authenticated user with access to the messaging module can request sent-message details from modules/messaging/SentMail.php by supplying an arbitrary mail_id value.
The sent-mail listing query correctly limits rows to the current authenticated user. However, the message body retrieval branch uses the client-controlled mail_id directly in a msg_outbox query and does not verify that the requested message belongs to the current session user. Because msg_outbox.mail_id is an auto-incrementing integer, an authenticated attacker can enumerate message identifiers and retrieve sent messages belonging to other users, including administrative users.
Attachments referenced by the exposed messages are also affected. DownloadWindow.php downloads records from user_file_upload by down_id without checking that the authenticated user owns the file or is authorized to access the message that references it. Direct mass enumeration of down_id depends on the deployment schema because newer schemas define download_id as a UUID, but once a vulnerable sent message is retrieved, the page exposes attachment download links that can be used without an ownership check.
Vulnerability
Root cause
Authenticated module dispatch (
Ajax.php:234-258):Ajax.phpincludes allowed modules for authenticated users.messaging/SentMail.phpis available in the messaging menu for admin, teacher, parent, and student profiles.Sent-mail listing is owner-filtered (
modules/messaging/SentMail.php:191-202):The listing view only displays messages sent by the authenticated user.
Sent-mail body retrieval does not enforce ownership (
modules/messaging/SentMail.php:60-67):This query only filters by
mail_id. It does not requirefrom_user = User('USERNAME'), nor does it joinlogin_authenticationto validate the currentUSER_IDandPROFILE_ID.The inbox body retrieval shows the intended authorization pattern (
modules/messaging/Inbox.php:441-449):The inbox path validates the message recipient against the authenticated user's identity. The sent-mail path lacks the equivalent sender-side check.
Attachment download lacks authorization (
DownloadWindow.php:67-100):The download endpoint retrieves and returns file content by
download_idwithout verifyingUSER_ID,PROFILE_ID,SCHOOL_ID,SYEAR,FILE_INFO, message ownership, or recipient/sender authorization.
Confirmed source-to-sink path
An authenticated user reaches
Ajax.phpwith an allowed messaging module.Ajax.phpincludesmodules/messaging/SentMail.php.The attacker supplies
modfunc=bodyand a chosenmail_id.SentMail.phpqueriesmsg_outboxusing only the suppliedmail_id.The returned row is rendered to the response, including subject, sender, recipients, body, timestamp, and attachment links.
If an exposed message has
mail_attachment,SentMail.phpqueriesuser_file_uploadby attachment IDs and rendersDownloadWindow.php?down_id=<DOWNLOAD_ID>links.DownloadWindow.phpreturns the referenced file content without checking that the current user is authorized to access the file.
Why mass exfiltration by mail_id is supported by code
The message identifier is sequential by schema:
Because mail_id values are predictable integers and the body query lacks ownership constraints, an attacker can request mail_id=1, mail_id=2, mail_id=3, and so on, collecting every existing msg_outbox row returned by the application.
Impact
An authenticated low-privileged user can read sent-message content belonging to other accounts. The exposed data may include:
message subject
message body
sender username and display name
recipients, CC, and BCC values stored in the outbox row
send timestamp
attachment references and downloadable attachment content
This can result in broad confidentiality compromise of internal messaging data. The impact is amplified by the sequential mail_id design, which allows practical enumeration of the sent-message table from the web interface.
Relevant code:
Ajax.php:234-258(authenticated module include)modules/messaging/Menu.php:29-62(messaging module available to admin, teacher, parent, and student profiles)modules/messaging/SentMail.php:60-67(vulnerable sent-message body query)modules/messaging/SentMail.php:144-174(attachment link rendering from exposed message)modules/messaging/SentMail.php:191-202(owner-filtered sent-message listing)modules/messaging/Inbox.php:441-449(contrasting owner-filtered inbox body query)DownloadWindow.php:67-100(unauthorized file download bydown_id)install/OpensisSchemaMysqlInc.sql:1339-1354(msg_outbox.mail_idauto-increment schema)install/OpensisUpdateSchemaMysql.sql:1930-1943(user_file_upload.download_idschema)
PoC
Preconditions
openSIS Classic 9.3 instance with messaging enabled.
Any valid authenticated user account with access to
messaging/SentMail.php.At least one existing sent message in
msg_outbox.
Step 1 - Authenticate as a low-privileged user
Sign in to openSIS as any non-administrative user who can access the messaging module.
Step 2 - Request a sent-message body by explicit mail_id
Request:
Expected vulnerable result:
If
msg_outbox.mail_id = 1exists, the response contains the sent-message detail view.The response is returned even when the authenticated user is not the sender of that message.
Step 3 - Enumerate sequential message identifiers
Repeat the same request with increasing mail_id values:
Expected vulnerable result:
Existing
mail_idvalues return arbitrary sent-message content.Missing
mail_idvalues return no message content.Authorization is not tied to the authenticated user's username, user ID, or profile ID.
Step 4 - Download an attachment exposed by a retrieved message
If the retrieved message contains an attachment, the response renders a link similar to:
Request:
Expected vulnerable result:
DownloadWindow.phpreturns the file content associated with<DOWNLOAD_ID>.The endpoint does not validate ownership or message-level authorization before returning the file.
Evidence of Exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-8406 to refer to this issue from now on.
System Information
openSIS Classic
Version: 9.3 Community Edition
Operating System: Any deployment running the affected openSIS Classic messaging module
References
Github Repository: https://github.com/OS4ED/openSIS-Classic
Patch: https://github.com/OS4ED/openSIS-Classic/commit/c45d43146167324bae06bdf09de3e4bd2e5e478f
Mitigation
An updated version of openSIS Classic is available at the vendor page.
Credits
The vulnerability was discovered by Daniel Celis, an independent security researcher.
Timeline
Vulnerability discovered
Vendor contacted
Vendor replied
Follow-up with vendor
Vendor confirmed
Vulnerability patched
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.













