VYPR
Critical severityNVD Advisory· Published Sep 12, 2018· Updated Aug 5, 2024

CVE-2018-16974

CVE-2018-16974

Description

An issue was discovered in Elefant CMS before 2.0.7. There is a PHP Code Execution Vulnerability in apps/filemanager/upload/drop.php by using /filemanager/api/rm/.htaccess to remove the .htaccess file, and then using a filename that ends in .php followed by space characters (for bypassing the blacklist).

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Elefant CMS before 2.0.7 allows authenticated attackers to upload and execute arbitrary PHP code by deleting the .htaccess file and using trailing spaces to bypass file extension checks.

Vulnerability

In Elefant CMS versions prior to 2.0.7, the file upload functionality in apps/filemanager/upload/drop.php fails to properly validate file extensions. By first using the /filemanager/api/rm/.htaccess endpoint to delete the protective .htaccess file in the /files/ directory, an attacker can then upload a file with a name ending in .php followed by space characters (e.g., shell.php ). The blacklist-based validation does not strip trailing spaces, allowing the file to be saved with a .php extension that the web server will execute [1][4]. The commit fixing this issue introduces consistent trim() on file paths across multiple API endpoints [2].

Exploitation

The attacker must be authenticated as a user with file upload permissions. The first step is to send a POST request to /filemanager/api/rm/.htaccess to remove the .htaccess file that typically blocks direct access to uploaded PHP files. Next, the attacker uploads a file via /filemanager/api/upload/drop with a filename ending in .php appended with space characters (e.g., evil.php ). The validation routine fails to strip trailing spaces, so the file is accepted and stored in the /files/ directory [4]. No race condition or additional user interaction is required.

Impact

Successful exploitation allows the attacker to execute arbitrary PHP code on the server under the web server's privileges. This leads to complete compromise of the CMS installation, including reading, writing, or deleting files, accessing databases, and potentially pivoting to other systems on the same network. The attack does not require any special privilege beyond the ability to upload files [1][4].

Mitigation

The vulnerability is fixed in Elefant CMS version 2.0.7, released on September 12, 2018 [3]. All users should upgrade immediately to 2.0.7 or later. The fix applies trim() to file paths in the affected API functions post_drop, post_rm, get_ls, and others [2]. As a workaround, administrators can ensure the /files/.htaccess file is restored after any accidental deletion, but upgrading is the definitive solution. This CVE is not listed in CISA's Known Exploited Vulnerabilities catalog.

AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
elefant/cmsPackagist
< 2.0.72.0.7

Affected products

1

Patches

1
49ba8cc24e9f

Fixed filemanager file upload validations, re: #287

6 files changed · +22 17
  • apps/filemanager/handlers/embed.php+3 1 modified
    @@ -110,7 +110,9 @@
     			return;
     		}
     		
    -		if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe)$/i', $_POST['newName'])) {
    +		$_POST['newName'] = trim ($_POST['newName']);
    +		
    +		if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe|htaccess|htpasswd)$/i', $_POST['newName'])) {
     			echo __ ('Invalid file type');
     			return;
     		}
    
  • apps/filemanager/handlers/redactor/upload.php+2 2 modified
    @@ -41,9 +41,9 @@
     }
     
     // some browsers may urlencode the file name
    -$_FILES['file']['name'] = urldecode ($_FILES['file']['name']);
    +$_FILES['file']['name'] = trim (urldecode ($_FILES['file']['name']));
     
    -if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe)$/i', $_FILES['file']['name'])) {
    +if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe|htaccess|htpasswd)$/i', $_FILES['file']['name'])) {
     	echo json_encode (array ('error' => __ ('Cannot upload executable files due to security.')));
     	return;
     }
    
  • apps/filemanager/handlers/upload/drop.php+2 2 modified
    @@ -45,9 +45,9 @@
     }
     
     // some browsers may urlencode the file name
    -$_FILES['file']['name'] = urldecode ($_FILES['file']['name']);
    +$_FILES['file']['name'] = trim (urldecode ($_FILES['file']['name']));
     
    -if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe)$/i', $_FILES['file']['name'])) {
    +if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe|htaccess|htpasswd)$/i', $_FILES['file']['name'])) {
     	echo json_encode (array ('success' => false, 'error' => __ ('Cannot upload executable files due to security.')));
     	return;
     }
    
  • apps/filemanager/handlers/upload.php+2 2 modified
    @@ -49,7 +49,7 @@
     }
     
     for ($i = 0; $i < count ($_FILES['file']['name']); $i++) {
    -	$_FILES['file']['name'][$i] = urldecode ($_FILES['file']['name'][$i]);
    +	$_FILES['file']['name'][$i] = trim (urldecode ($_FILES['file']['name'][$i]));
     	if (@file_exists ($root . $_POST['path'] . '/' . $_FILES['file']['name'][$i])) {
     		$page->title = __ ('File Already Exists') . ': ' . $_FILES['file']['name'][$i];
     		echo '<p>' . __ ('A file by that name already exists.') . '</p>';
    @@ -62,7 +62,7 @@
     		echo '<p><a href="/filemanager">' . __ ('Back') . '</a></p>';
     		return;
     	}
    -	if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe)$/i', $_FILES['file']['name'][$i])) {
    +	if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe|htaccess|htpasswd)$/i', $_FILES['file']['name'][$i])) {
     		$page->title = __ ('Invalid File Name') . ': ' . $_FILES['file']['name'][$i];
     		echo '<p>' . __ ('Cannot upload executable files due to security.') . '</p>';
     		echo '<p><a href="/filemanager">' . __ ('Back') . '</a></p>';
    
  • apps/filemanager/lib/API.php+9 9 modified
    @@ -13,7 +13,7 @@ class API extends Restful {
     	 * Handle list directory requests (/filemanager/api/ls).
     	 */
     	public function get_ls () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     
     		$res = FileManager::dir ($file);
     		if (! $res) {
    @@ -43,7 +43,7 @@ public function get_dirs () {
     	 * Handle Bitly link requests (/filemanager/api/bitly).
     	 */
     	public function get_bitly () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     		$link = $this->controller->absolutize ('/files/' . $file);
     		return BitlyLink::lookup ($link);
     	}
    @@ -52,7 +52,7 @@ public function get_bitly () {
     	 * Handle remove file requests (/filemanager/api/rm).
     	 */
     	public function post_rm () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     
     		$res = FileManager::unlink ($file);
     		if (! $res) {
    @@ -71,7 +71,7 @@ public function post_rm () {
     	 * Note: Erases the contents of the folder as well.
     	 */
     	public function post_rmdir () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     
     		$res = FileManager::rmdir ($file, true);
     		if (! $res) {
    @@ -89,7 +89,7 @@ public function post_rmdir () {
     	 * Handle rename requests (/filemanager/api/mv).
     	 */
     	public function post_mv () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     
     		$is_folder = FileManager::verify_folder ($file) ? true : false;
     		
    @@ -114,7 +114,7 @@ public function post_mv () {
     	 * folders.
     	 */
     	public function post_drop () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     		
     		if (! FileManager::move ($file, $_POST['folder'])) {
     			return $this->error (FileManager::error ());
    @@ -133,7 +133,7 @@ public function post_drop () {
     	 * Handle make directory requests (/filemanager/api/mkdir).
     	 */
     	public function post_mkdir () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     		
     		if (! FileManager::mkdir ($file)) {
     			return $this->error (FileManager::error ());
    @@ -153,7 +153,7 @@ public function post_mkdir () {
     	 * be used to set an individual property's value.
     	 */
     	public function post_prop () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     		if (! FileManager::verify_file ($file)) {
     			return $this->error (__ ('Invalid file name'));
     		}
    @@ -200,7 +200,7 @@ public function post_prop () {
     	 * Handle unzip requests via (/filemanager/api/unzip).
     	 */
     	public function post_unzip () {
    -		$file = urldecode (join ('/', func_get_args ()));
    +		$file = trim (urldecode (join ('/', func_get_args ())));
     		if (! FileManager::verify_file ($file)) {
     			return $this->error (__ ('Invalid file name'));
     		}
    
  • apps/filemanager/lib/FileManager.php+4 1 modified
    @@ -160,6 +160,9 @@ public static function unlink ($file) {
     		} elseif (! self::verify_file ($file)) {
     			self::$error = __ ('File not found');
     			return false;
    +		} elseif (! self::verify_file_name ($file)) {
    +			self::$error = __ ('Invalid file name');
    +			return false;
     		} elseif (! unlink (self::root () . $file)) {
     			self::$error = __ ('Unable to delete') . ' ' . $file;
     			return false;
    @@ -405,7 +408,7 @@ public static function verify_file_name ($name) {
     		if (! preg_match ('/^[a-zA-Z0-9 _-]+\.[a-zA-Z0-9_-]+$/', $name)) {
     			return false;
     		}
    -		if (preg_match ('/\.php$/i', $name)) {
    +		if (preg_match ('/\.(php|phtml|pht|php3|php4|php5|phar|js|rb|py|pl|sh|bash|exe|htaccess|htpasswd)$/i', $name)) {
     			return false;
     		}
     		return true;
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.