CVE-2026-25057 Overview
CVE-2026-25057 is a critical path traversal vulnerability affecting MarkUs, a web application designed for the submission and grading of student assignments. The vulnerability exists in the assignment configuration upload functionality (courses/<:course_id>/assignments/upload_config_files) where instructors can upload zip files to create assignments from exported configurations. The zip file entry names are used to construct file paths without proper validation, allowing authenticated instructors to write files to arbitrary locations on the server filesystem.
Critical Impact
Authenticated instructors with access to the assignment configuration upload feature can exploit this vulnerability to write arbitrary files outside the intended directory, potentially leading to remote code execution, configuration tampering, or complete server compromise.
Affected Products
- MarkUs versions prior to 2.9.1
Discovery Timeline
- 2026-02-09 - CVE CVE-2026-25057 published to NVD
- 2026-02-09 - Last updated in NVD database
Technical Details for CVE-2026-25057
Vulnerability Analysis
This vulnerability is classified as CWE-23 (Relative Path Traversal). The flaw resides in the assignments_controller.rb file within the MarkUs application, specifically in the code handling zip file extraction for automated test configurations. When an instructor uploads a zip file containing assignment configuration, the application iterates through zip file entries and constructs destination paths by directly joining the entry names with the target directory without validating whether the resulting path remains within the intended directory boundary.
An attacker with instructor privileges can craft a malicious zip file containing entries with path traversal sequences (e.g., ../../../etc/cron.d/malicious) to escape the designated autotest_files_dir directory and write files to arbitrary locations on the server. This can result in remote code execution if the attacker writes executable scripts to locations that are subsequently processed by the system.
Root Cause
The root cause is insufficient input validation when processing zip file entry names. The original code used File.join() to combine the autotest files directory with the filename extracted from the zip entry without canonicalizing or validating the resulting path. This allowed directory traversal sequences (../) embedded in zip entry names to escape the intended destination directory and write files elsewhere on the filesystem.
Attack Vector
The attack requires network access and high privileges (instructor role). An authenticated instructor can exploit this vulnerability by:
- Creating a malicious zip file with entries containing path traversal sequences in their filenames
- Uploading this zip file through the assignment configuration upload endpoint
- The server extracts the zip entries, writing files to attacker-controlled paths outside the intended directory
The vulnerability enables cross-scope impact, meaning a compromised instructor account can affect resources beyond the application boundary, including system files and configurations.
# Vulnerable code pattern (before patch)
zip_file.glob(test_file_glob_pattern) do |entry|
zip_file_path = Pathname.new(entry.name)
filename = zip_file_path.relative_path_from(CONFIG_FILES[:automated_tests_dir_entry])
file_path = File.join(assignment.autotest_files_dir, filename.to_s)
# No validation that file_path stays within autotest_files_dir
if entry.directory?
FileUtils.mkdir_p(file_path)
else
FileUtils.mkdir_p(File.dirname(file_path))
test_file_content = entry.get_input_stream.read
File.write(file_path, test_file_content, mode: 'wb')
end
end
The patched code (commit 0ca002a1f0071c7a00dbb2ed34fede57323c5dc7) adds proper path canonicalization using File.expand_path() and validates that the resulting path starts with the intended directory:
zip_file.glob(test_file_glob_pattern) do |entry|
zip_file_path = Pathname.new(entry.name)
filename = zip_file_path.relative_path_from(CONFIG_FILES[:automated_tests_dir_entry])
- file_path = File.join(assignment.autotest_files_dir, filename.to_s)
+ file_path = File.expand_path(File.join(assignment.autotest_files_dir, filename.to_s))
+
+ unless file_path.start_with?(File.expand_path(assignment.autotest_files_dir))
+ raise I18n.t('errors.invalid_zip_entry', entry_name: filename.to_s)
+ end
+
if entry.directory?
FileUtils.mkdir_p(file_path)
else
FileUtils.mkdir_p(File.dirname(file_path))
- test_file_content = entry.get_input_stream.read
- File.write(file_path, test_file_content, mode: 'wb')
+ # Extract the entry to file_path. destination_directory is '/' because file_path is an absolute path
+ entry.extract(file_path, destination_directory: '/')
end
end
end
Source: GitHub Commit Changes
Detection Methods for CVE-2026-25057
Indicators of Compromise
- Unexpected files appearing outside the MarkUs autotest_files_dir directory following assignment configuration uploads
- Web server logs showing POST requests to /courses/<course_id>/assignments/upload_config_files with unusually large or suspicious zip files
- New cron jobs, scripts, or configuration files created by the web server process user
- File system modifications in sensitive directories (e.g., /etc, /var, application directories) with timestamps correlating to instructor zip uploads
Detection Strategies
- Implement file integrity monitoring (FIM) on critical system directories to detect unauthorized file creation or modification
- Monitor web application logs for requests to the upload_config_files endpoint and correlate with file system activity outside expected directories
- Configure WAF rules to inspect uploaded zip files for path traversal patterns in entry names
- Deploy endpoint detection to alert on the web server process writing files outside application-designated directories
Monitoring Recommendations
- Enable verbose logging for the MarkUs application to capture all file operations during zip extraction
- Implement audit logging on the server to track all file creation events by the web application user
- Set up alerts for any errors related to "invalid_zip_entry" which indicates the patched version blocking traversal attempts
- Monitor for anomalous instructor account activity, particularly around assignment configuration uploads
How to Mitigate CVE-2026-25057
Immediate Actions Required
- Upgrade MarkUs to version 2.9.1 or later immediately
- Review file system for any unauthorized files that may have been written outside the autotest_files_dir directory
- Audit instructor account activity logs for suspicious configuration upload activity
- If upgrade is not immediately possible, consider temporarily disabling the assignment configuration upload feature
Patch Information
The vulnerability is fixed in MarkUs version 2.9.1. The patch implements proper path canonicalization using File.expand_path() and validates that extracted file paths remain within the designated autotest_files_dir directory. Organizations should upgrade to version 2.9.1 or later as documented in the GitHub Release v2.9.1. Additional details are available in the GitHub Security Advisory GHSA-mccg-p332-252h.
Workarounds
- Restrict access to the assignment configuration upload feature to only trusted administrators until the patch can be applied
- Implement network-level access controls to limit which IP addresses can access instructor-level functionality
- Deploy a web application firewall (WAF) with rules to detect and block zip files containing path traversal sequences
- Run the MarkUs application in a containerized or sandboxed environment to limit the impact of file write operations outside the application directory
# Example: Check MarkUs version to verify patch status
grep -r "VERSION" /path/to/markus/config/ || cat /path/to/markus/VERSION
# Verify no unauthorized files exist outside autotest directories
find /var/www/markus -name "*.rb" -newer /var/www/markus/config/application.rb -ls
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


