CVE-2018-11331 (PHP, published 2018-05-21T21:29Z)
Description: value: An issue was discovered in Pluck before 4.7.6. Remote PHP code execution is possible because the set of disallowed filetypes for uploads in missing some applicable ones such as .phtml and .htaccess.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-434 \u2014 Unrestricted Upload of File with Dangerous Type
The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
Repository: https://github.com/pluck-cms/pluck
Files changed:
data/inc/editpage.php
data/inc/files.php
data/inc/functions.all.php
data/inc/images.php
data/modules/.htaccess
data/themes/.htaccess
files/.htaccess
images/.htaccess
Commit message: bugfix for XSS and backdoor file upload found by s7acktrac3 issue #58


Vulnerable code:
			$seoname = save_page($title, $_POST['content'], $_POST['hidden'], $_POST['sub_page'], $_POST['description'], $_POST['keywords'], $module_additional_data, $_GET['page']);
			$seoname = save_page($title, $_POST['content'], $_POST['hidden'], $_POST['sub_page'], $_POST['description'], $_POST['keywords'], $module_additional_data);
		if (!copy($_FILES['filefile']['tmp_name'], 'files/'.$_FILES['filefile']['name']))
			if (strcasecmp(substr($_FILES['filefile']['name'], -3),'php') == 0){
				if (!rename('files/'.$_FILES['filefile']['name'], 'files/'.$_FILES['filefile']['name'].'.txt')){
				chmod('files/'.$_FILES['filefile']['name'].'.txt', 0775);
				chmod('files/'.$_FILES['filefile']['name'], 0775);
					<strong><?php echo $lang['files']['name']; ?></strong> <?php echo $_FILES['filefile']['name']; ?>
					<strong><?php echo $lang['files']['size']; ?></strong> <?php echo $_FILES['filefile']['size'].' '.$lang['images']['bytes']; ?>
					<strong><?php echo $lang['files']['type']; ?></strong> <?php echo $_FILES['filefile']['type']; ?>
		if (!copy($_FILES['imagefile']['tmp_name'], 'images/'.$_FILES['imagefile']['name']))
					<strong><?php echo $lang['images']['name']; ?></strong> <?php echo $_FILES['imagefile']['name']; ?>
					<strong><?php echo $lang['images']['size']; ?></strong> <?php echo $_FILES['imagefile']['size'].' '.$lang['images']['bytes']; ?>
					<strong><?php echo $lang['images']['type']; ?></strong> <?php echo $_FILES['imagefile']['type']; ?>

Fixed code:
			$seoname = latinOnlyInput(save_page($title, $_POST['content'], $_POST['hidden'], $_POST['sub_page'], $_POST['description'], $_POST['keywords'], $module_additional_data, $_GET['page']));
			$seoname = latinOnlyInput(save_page($title, $_POST['content'], $_POST['hidden'], $_POST['sub_page'], $_POST['description'], $_POST['keywords'], $module_additional_data));
		if (!copy($_FILES['filefile']['tmp_name'], 'files/'.latinOnlyInput(latinOnlyInput($_FILES['filefile']['name']))))
			$lastfour = strtolower(substr(latinOnlyInput($_FILES['filefile']['name']), -4));
			$lastfive = strtolower(substr(latinOnlyInput($_FILES['filefile']['name']), -5));
			$blockedExtentions = array('.php','php3','php4','php5','php6','php7','phtml');
			if (in_array($lastfour, $blockedExtentions) or in_array($lastfive, $blockedExtentions) ){
				if (!rename('files/'.latinOnlyInput($_FILES['filefile']['name']), 'files/'.latinOnlyInput($_FILES['filefile']['name']).'.txt')){
				chmod('files/'.latinOnlyInput($_FILES['filefile']['name']).'.txt', 0775);
				chmod('files/'.latinOnlyInput($_FILES['filefile']['name']), 0775);
					<strong><?php echo $lang['files']['name']; ?></strong> <?php echo latinOnlyInput($_FILES['filefile']['name']); ?>
					<strong><?php echo $lang['files']['size']; ?></strong> <?php echo latinOnlyInput($_FILES['filefile']['size']).' '.$lang['images']['bytes']; ?>
					<strong><?php echo $lang['files']['type']; ?></strong> <?php echo latinOnlyInput($_FILES['filefile']['type']); ?>
			if (!($file == '.htaccess')){
			}
	$var = htmlspecialchars($var, ENT_COMPAT, 'UTF-8', false);
/**
 * latinOnlyInput from a URL, to make it ready for saving in a file.
 *
 * @since 4.7.5
 * @package all
 * @param string $var Variable 
 * @return string The sanitized variable.
 * 
 * Added as bugfix for XSS and backdoor file upload found by s7acktrac3
 */
function latinOnlyInput($var) {
	$var = str_replace(chr(0), '', $var);
	$var = preg_replace("/[^a-zA-Z0-9.\ -_]+/", "", $var);;
	return $var;
}


		if (!copy($_FILES['imagefile']['tmp_name'], 'images/'.latinOnlyInput($_FILES['imagefile']['name'])))
					<strong><?php echo $lang['images']['name']; ?></strong> <?php echo latinOnlyInput($_FILES['imagefile']['name']); ?>
					<strong><?php echo $lang['images']['size']; ?></strong> <?php echo latinOnlyInput($_FILES['imagefile']['size']).' '.$lang['images']['bytes']; ?>
					<strong><?php echo $lang['images']['type']; ?></strong> <?php echo latinOnlyInput($_FILES['imagefile']['type']); ?>
			if (!($image == '.htaccess')){
			}
<FilesMatch \.php$>
    SetHandler None
</FilesMatch>

<FilesMatch \.phtml>
    SetHandler None
</FilesMatch>

Options -ExecCGI
<FilesMatch \.php$>
    SetHandler None
</FilesMatch>

<FilesMatch \.phtml>
    SetHandler None
</FilesMatch>

Options -ExecCGI
<FilesMatch \.php$>
    SetHandler None
</FilesMatch>

<FilesMatch \.phtml>
    SetHandler None
</FilesMatch>

Options -ExecCGI
<FilesMatch \.php$>
    SetHandler None
</FilesMatch>

<FilesMatch \.phtml>
    SetHandler None
</FilesMatch>

Options -ExecCGI