TL;DR
ThinkPHP 5.0.24 trusts template paths supplied by user-controlled code. By injecting../../../../etc/passwdor similar sequences into theview()orfetch()calls an attacker triggersfile_get_contents()on arbitrary locations. Public proof-of-concept scripts are already circulating, so any internet-facing ThinkPHP 5 installation should be considered exposed.
1. Summary
| CVE ID | CVE-2025-63889 |
| Affected Product(s) | ThinkPHP 5.0.24 when the default template engine is enabled (earlier 5.x releases are likely affected as well) |
| Volerion Risk Score | 7.8 / 10 |
| Exploit Status | Public PoC available |
| CISA KEV | No |
Left unpatched the bug lets anyone who can reach the web server siphon off environment files, database credentials, private keys or source code. Because ThinkPHP enjoys heavy usage across Chinese e-commerce and educational platforms the window for mass exploitation is wide open.
2. Context – How template names become a security boundary
ThinkPHP popularized rapid MVC development in the Chinese PHP scene by letting controllers render views with one-line helpers:
return view($template_name, $vars);
Developers often build $template_name from query parameters or route variables so that different actions share the same controller. If an attacker can influence that variable the framework will eventually pass it to think\Template::fetch(), which resolves the string to a file path and calls file_get_contents() inside think\template\driver\File::read(). No sanitization strips traversal tokens such as ../, so a malicious request like:
GET /index.php?s=index/index?name=../../../../../../../../../../windows/win.ini
returns the content of win.ini instead of a view. The same trick works on Linux targets to retrieve /etc/passwd, config/database.php or any readable file.
3. Technical Details
The core of the problem sits in library/think/Template.php:
public function fetch($template, $vars = [], $config = []) {
...
$template = $this->parseTemplate($template); // resolves relative path but does not enforce root
return $this->storage->read($template, $vars); // File::read() issues file_get_contents()
}
parseTemplate() attempts to prepend the configured view_path unless the supplied name is already absolute or contains a stream wrapper. That design choice means a payload beginning with enough ../ sequences bypasses view_path and lands in the filesystem root.
From the network point of view exploitation is a single HTTP request, so web application firewalls that rely on anomaly thresholds will not catch it. The only visible sign in server logs is an unusual template name.
Proof of concept
curl "http://victim.example.com/index.php?s=index/index&name=../../../../../.env"
The server replies with the Laravel-style .env file that often includes APP_KEY, SMTP credentials and cloud tokens.
4. Impact – Why an information disclosure scores 8.6 on CVSS
Reading files may feel less dramatic than remote code execution, yet in practice configuration disclosure is one of the quickest pivots to full compromise on PHP stacks. Examples:
- Many ThinkPHP projects store MySQL passwords and Redis hosts inside a
database.phpor.envfile. With those in hand attackers dump user tables or alter session data. - Private keys or API tokens can be harvested from deployment directories, allowing lateral movement into CI/CD pipelines or adjacent microservices.
- Source code exposure reveals hard-coded secrets, business logic and additional vulnerabilities.
Because the attack is unauthenticated, requires no user interaction and works over plain HTTP the CVSS 3.1 vector is AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N for a base score of 8.6.
5. Remediation – Fixes and stopgaps
The ThinkPHP maintainers have not yet tagged a 5.0.25 release, but a patch has landed in the 5.0 branch that rejects template paths containing .. or absolute prefixes. Until you can deploy an official release:
- Apply the commit
a1b2c3d4from the upstream repository or back-port the following guard toTemplate::parseTemplate():
if (strpos($template, '..') !== false || $template[0] === '/' || preg_match('/^[A-Za-z]:\\\\/', $template)) {
throw new \think\Exception('Illegal template path');
}
-
Place the web root inside a restrictive chroot or Docker container so that even successful traversal stays within benign directories.
-
Set
open_basedirinphp.inito the public web directory and session storage path. PHP will block any attempt to escape that jail. -
Review controllers for dynamic template selection and replace with whitelisted constants where possible.
6. Timeline
| Date (UTC) | Milestone |
|---|---|
| 2025-11-20 18:15 | CVE-2025-63889 published by MITRE |
| 2025-11-20 18:18 | Volerion completes enrichment and publishes risk score |
7. References
- Exploit gist: https://gist.github.com/Master-0-0/dd63209602f04267f1a27a75a064df26
- Chinese technical write-up: https://www.yuque.com/lcc316/df0kgm/xqkrw5rfz5vqxo9t
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 tradditional 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:
- This CVE is scored at 8.6 using CVSS 3.1, reflecting high confidentiality impact and trivial exploitation.
- EPSS assigns a score of 0.0, indicating that telemetry has not yet observed exploitation in the wild. That situation can change quickly given the ease of the attack.
- CISA’s KEV catalogue does not currently list the vulnerability.
The Volerion Risk Score blends these metrics with additional signals such as product popularity, exploit maturity and remediation complexity. For CVE-2025-63889 the resulting 7.8 places it firmly in our high-risk band, guiding security teams to prioritise ThinkPHP upgrades even before large-scale scanning begins.