Skip to content
Go back

[CVE-2025-63888] ThinkPHP 5.0.24 Template File Inclusion Drops a Remote Shell

Volerion Research

TL;DR
ThinkPHP 5.0.24 treats the template name provided to the view() helper as a filesystem path with almost no validation. By traversing out of the template directory an attacker can point the engine at a user-controlled upload such as shell.jpg, which ThinkPHP then executes with include. The bug is unauthenticated, trivial to exploit and already demonstrated in public gists.


1. Summary

CVE ID CVE-2025-63888
Affected Product(s) ThinkPHP 5.0.24 when using the default File template driver
Volerion Risk Score 7.9 / 10
Exploit Status Public PoC available
CISA KEV No

Because most ThinkPHP applications allow file uploads for avatars or product images, gaining a foothold usually boils down to dropping a payload and requesting a crafted route. No credentials or special options are required.


2. Context – Why another ThinkPHP bug deserves attention

ThinkPHP remains one of the most popular PHP frameworks for Chinese-language e-commerce sites and small business portals. Search engines regularly index tens of thousands of internet-facing ThinkPHP instances, many of which still run in production on version 5 even though version 8 is current. These deployments often sit behind CDN front ends but still expose /index.php routes that reach the vulnerable template logic.

Historically, ThinkPHP bugs have fueled mass exploitation waves: the 2018 RCE (CVE-2018-20062) became a staple of botnets such as Mirai; the 2022 variable overwrite flaw (CVE-2022-3075) saw similar uptake. Attackers add new ThinkPHP exploits to automated crawlers as soon as code surfaces, which means defenders have little breathing room once a proof-of-concept lands.


3. Technical Details – From directory traversal to code execution

The File template driver lives in thinkphp/library/think/template/driver/File.php. Rendering a view boils down to:

public function read($template) {
    $template = $this->parseTemplateFile($template);
    include $template;              // Vulnerable include
}

parseTemplateFile() attempts to locate the requested file by concatenating the user-supplied template name with the configured view path. Unfortunately it does not strip traversal sequences such as ../. Consequently a request like:

http://example.com/index.php?s=/index/test&template=../../uploads/20210510/shell.jpg

resolves to:

/var/www/html/uploads/20210510/shell.jpg

If shell.jpg contains PHP code hidden after image headers, include passes control to that code under the webserver account, yielding full remote code execution.

Exploit prerequisites

  1. Ability to upload or place a file somewhere reachable by the web server. Most sites expose /upload or /public/static for media files.
  2. Knowledge (or guessing) of the relative path from the view directory to the upload directory.

No authentication, CSRF token or special server configuration is necessary.

Why php_flag engine off tricks fail here

Hardening guides often suggest disabling PHP execution in upload directories through web-server configurations like php_flag engine off (Apache) or try_files (Nginx). These mitigate direct execution but do not matter when the file is executed by an upstream include within PHP itself. Once the template engine resolves the path, PHP interprets the bytes regardless of MIME type or file extension.


4. Impact – One request to own the application

Successful exploitation grants the attacker the same privileges as the PHP process. Typical consequences include dumping database credentials from config.php, modifying front-end code to inject credit-card skimmers and pivoting further into the hosting environment. Shared hosting setups that give multiple customers a single PHP-FPM pool are particularly exposed, as compromise of one virtual host affects all others.


5. Remediation – Patch or lock down template paths

  1. Upgrade ThinkPHP
    The project has released patches after 5.0.24 that tighten path validation. Upgrade to the latest 5.x branch or, preferably, move to the still-maintained 8.x line.
  2. Back-port the fix
    Where upgrading is not immediately possible, patch parseTemplateFile() to strip ../ sequences and reject absolute paths.
  3. Restrict uploads
    Store user files outside the document root and configure the application to serve them through a dedicated handler or CDN. Even if inclusion is attempted, the path will not resolve on disk.
  4. Web-application firewalls
    Temporary mitigation can be achieved by blocking requests whose template parameter contains ../ or begins with /.

6. Timeline

Date (UTC)Milestone
2025-11-20 18:15CVE-2025-63888 published
2025-11-20 18:18Volerion completes enrichment and publishes risk score

7. References


About Volerion

Volerion delivers AI-driven enrichment minutes after a CVE goes live. A single call to our REST API returns CVSS 4.0 vectors, exploitability metrics and affected products complete with remediation. Additionally, we offer different scoring profiles, complete with insight into the eight comprehensive categories that make up the final score. Our API is also available in the traditional NVD API 2.0 format, so integration is as simple as swapping hosts. Spend less time parsing CVEs and more time closing them.

How the Volerion Risk Score Fits With CVSS, EPSS and KEV

At the time of writing:

The Volerion Risk Score brings these signals together and layers them with additional factors such as affected product prevalence, exploit maturity and remediation effort. For CVE-2025-63888 the score is 7.9, placing it firmly in our high-risk band despite the absence of a KEV mandate or EPSS rating.


Share this post on:

Previous Post
[CVE-2025-63889] ThinkPHP 5.0.24 Lets Attackers Read Any File on the Server
Next Post
[CVE-2025-64502] Parse Server Leaks MongoDB Query Plans to Anyone Without a Master Key