Skip to content

Fixed critical RCE vulnerability in `upload_proof_file` by implementing strict server-side extension validation and secure file renaming. The logic no longer trusts client-side MIME types, ensuring malicious PHP scripts cannot be uploaded or executed. Validates against a strict allowlist (jpg, png, pdf) and sanitizes filenames.

Notifications You must be signed in to change notification settings

ayoproxy/-Security-Patch-File-Upload-Vulnerability-RCE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

Security Patch Report — File Upload Vulnerability (RCE) ⚠️

Security Status Tech Stack

Author: Anthony Ayodeji (AyoProxy)

Executive summary

A critical remote code execution (RCE) risk was found in a legacy file-upload flow used by the "Proof of Ownership" feature. The implementation relied on client-supplied metadata (browser-provided MIME types and original filenames) to validate and store uploads. An attacker could spoof these values and upload executable payloads (e.g., a .php shell) disguised as images, which could then be executed on the server.

I implemented a defense-in-depth remediation that eliminates this attack vector by enforcing strict server-side validation, deterministic renaming, and cross-checking content metadata. The changes fully mitigate the risk of uploading executable files and make any bypass attempts inert.


Vulnerability details

  • Root cause: The upload handler trusted client-provided MIME type and preserved original filenames and extensions when saving files.
  • Attack vector: An attacker modifies the HTTP request (Content-Type and filename) to submit a malicious script disguised as an image (for example, a .php file reported as image/jpeg). If saved with an executable extension and accessible under the web root, the script could be executed.
  • Impact: Remote code execution, data disclosure, and full application compromise.
  • Likelihood: High for any publicly reachable upload endpoint that uses client-supplied metadata for validation.
  • Evidence: Legacy handler validated using $_FILES['file']['type'] and stored files using original filenames, enabling extension-based execution.

Fix summary (defense in depth)

The revised upload_proof_file workflow implements three core protections:

  1. Strict server-side extension allowlist

    • The server ignores client MIME-type claims and validates file types by allowed extensions only.
    • Allowed extensions: jpg, jpeg, png, pdf (case-insensitive).
    • Any file that does not match the allowlist is rejected with a security error.
  2. Deterministic server-side renaming and sanitization

    • Uploaded files are not stored using the original filename.
    • Files are renamed to a safe, application-controlled pattern (for example: proof_<timestamp>_<safe_id>.<ext>), where <ext> is one of the validated static extensions.
    • This prevents path traversal and ensures uploaded content cannot be saved with an executable extension.
  3. Deep content inspection and consistency checks

    • After extension validation, the server cross-checks file content (e.g., by reading file headers or using a server-side MIME detection library) to ensure the content matches the expected type for that extension.
    • If the extension and actual content disagree, the upload is rejected.
    • As an additional hardening step, consider running a lightweight image parser to confirm the file is a valid image (for jpg, png) rather than relying on header heuristics alone.

Implementation notes

  • Do not rely on client-provided Content-Type or $_FILES['file']['type'] — treat them as untrusted input.
  • Use a small allowlist of known safe extensions. Avoid allowing any server-executable extensions at all.
  • Use safe storage locations:
    • Store user-uploaded files outside the application code directories and web root if possible.
    • If files must be web-accessible, serve them through a dedicated handler that enforces content-type headers and denies script execution.
  • Sanitize and validate any derived identifiers (e.g., IMEI or user IDs) used in filenames; prefer hashing or encoding rather than passing raw user-controlled strings.
  • Consider additional mitigations:
    • Content-disposition and strict response headers (Content-Security-Policy, X-Content-Type-Options: nosniff) when serving uploaded files.
    • Virus/malware scanning for uploads.
    • Size limits and rate limiting per account/IP for upload endpoints.
    • Detailed audit logging for uploads (who, when, filename, checks performed).

Risk reduction and verification

  • Attack surface removed: Uploads cannot be stored with executable extensions, reducing chance of RCE via uploaded scripts.
  • Defense-in-depth: Even if an attacker bypasses extension checks, the renaming step forces a safe extension; deep content checks further invalidate disguised payloads.
  • Recommended tests:
    • Attempt to upload files with spoofed MIME types and executable extensions — confirm rejection.
    • Upload valid and corrupted image files to ensure content-inspection rejects corrupted or non-image payloads.
    • Confirm stored filenames match the server-generated naming pattern and never include user-supplied extensions or directory components.

Conclusion

The implemented changes convert a high-risk, client-trusted upload flow into a hardened, server-controlled one. By applying an extension allowlist, deterministic renaming, and content inspection, the system is now robust against the class of RCE attacks that arise from malicious file uploads.

Contact: Need a CyberSecurity Expert, Developer and Engineeer ==> LinkedIn

About

Fixed critical RCE vulnerability in `upload_proof_file` by implementing strict server-side extension validation and secure file renaming. The logic no longer trusts client-side MIME types, ensuring malicious PHP scripts cannot be uploaded or executed. Validates against a strict allowlist (jpg, png, pdf) and sanitizes filenames.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published