Skip to content

Commit

Permalink
Page Editor: Files manager - has Stored XSS via Uploading html file t…
Browse files Browse the repository at this point in the history
…hat has no extension. #23
  • Loading branch information
Awilum committed Nov 22, 2018
1 parent cf9024a commit 2631943
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 28 deletions.
131 changes: 103 additions & 28 deletions admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,6 @@ protected static function getPagesManagerPage()

$page = Content::processPage(PATH['pages'] . '/' . Http::get('page') . '/page.html', false, true);

// Array of forbidden types
$forbidden_types = ['html', 'htm', 'js', 'jsb', 'mhtml', 'mht',
'php', 'phtml', 'php3', 'php4', 'php5', 'phps',
'shtml', 'jhtml', 'pl', 'py', 'cgi', 'sh', 'ksh', 'bsh', 'c', 'htaccess', 'htpasswd',
'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl', 'empty'];

// Array of image types
$image_types = ['jpg', 'png', 'bmp', 'gif', 'tif'];

$files_path = PATH['pages'] . '/' . Http::get('page') . '/';

if (Http::get('delete_file') != '') {
Expand All @@ -390,33 +381,24 @@ protected static function getPagesManagerPage()
}
}

$file_uploader_message = '';

if (Http::post('upload_file')) {

if (Token::check(Http::post('token'))) {

$error = false;
if ($_FILES['file']) {
if ( ! in_array(Filesystem::fileExt($_FILES['file']['name']), $forbidden_types)) {
$filepath = $files_path.Text::safeString(basename($_FILES['file']['name'], Filesystem::fileExt($_FILES['file']['name']))).'.'.Filesystem::fileExt($_FILES['file']['name']);
$uploaded = move_uploaded_file($_FILES['file']['tmp_name'], $filepath);
if ($uploaded !== false && is_file($filepath)) {
//Notification::set('success', __('File was uploaded', 'filesmanager'));
} else {
$error = 'File was not uploaded';
}
} else {
$error = 'Forbidden file type';
$file = Admin::uploadFile($files_path);

if (is_array($file['error'])) {
$file_uploader_message = '';

foreach ($file['error'] as $msg) {
$file_uploader_message .= '<p>'.$msg.'</p>';
}
} else {
$error = 'File was not uploaded';
//$message = "File uploaded successfully".$newname;
}

if ($error) {
//Notification::set('error', __($error, 'filesmanager'));
}

//Request::redirect($site_url.'/admin/index.php?id=filesmanager&path='.$path);

} else { die('Request was denied because it contained an invalid security token. Please refresh the page and try again.'); }
}

Expand All @@ -429,6 +411,9 @@ protected static function getPagesManagerPage()
}
}

// Array of image types
$image_types = ['jpeg', 'png', 'gif', 'jpg'];

$files = [];
$_files = array_diff(scandir(PATH['pages'] . '/' . Http::get('page')), array('..', '.'));

Expand All @@ -451,6 +436,7 @@ protected static function getPagesManagerPage()
->assign('page_content', $page['content'])
->assign('templates', $templates)
->assign('files', $files)
->assign('file_uploader_message', $file_uploader_message)
->display();
}
break;
Expand Down Expand Up @@ -560,6 +546,95 @@ public static function isAdminArea() {
}
}

public static function uploadFile ($path, $file_field = 'file', $check_image = true, $random_name = false)
{
//Set max file size in bytes
$max_size = 1000000;

//Set default file extension whitelist
$whitelist_ext = ['jpeg', 'png', 'gif', 'jpg'];

//Set default file type whitelist
$whitelist_type = array('image/jpeg', 'image/jpg', 'image/png','image/gif');

//The Validation
// Create an array to hold any output
$out = ['error' => null];

//Make sure that there is a file
if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) {

// Get filename
$file_info = pathinfo($_FILES[$file_field]['name']);
$name = $file_info['filename'];
if (isset($file_info['extension'])) {
$ext = $file_info['extension'];
} else {
$out['error'][] = "Empty file Extension";
return $out;
}

//Check file has the right extension
if (!in_array($ext, $whitelist_ext)) {
$out['error'][] = "Invalid file Extension";
}

//Check that the file is of the right type
if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
$out['error'][] = "Invalid file Type";
}

//Check that the file is not too big
if ($_FILES[$file_field]["size"] > $max_size) {
$out['error'][] = "File is too big";
}

//If $check image is set as true
if ($check_image) {
if (!getimagesize($_FILES[$file_field]['tmp_name'])) {
$out['error'][] = "Uploaded file is not a valid image";
}
}

//Create full filename including path
if ($random_name) {

// Generate random filename
$tmp = str_replace(array('.',' '), array('',''), microtime());

if (!$tmp || $tmp == '') {
$out['error'][] = "File must have a name";
}
$newname = $tmp.'.'.$ext;
} else {
$newname = $name.'.'.$ext;
}

//Check if file already exists on server
if (file_exists($path.$newname)) {
$out['error'][] = "A file with this name already exists";
}

if (count($out['error'])>0) {
//The file has not correctly validated
return $out;
}

if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) {
//Success
$out['filepath'] = $path;
$out['filename'] = $newname;
return $out;
} else {
$out['error'][] = "Server Error!";
}

} else {
$out['error'][] = "No file uploaded";
return $out;
}
}

/**
* Get the Admin instance.
*
Expand Down
6 changes: 6 additions & 0 deletions views/templates/content/pages/editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
</div>
</div>

<?php if ($file_uploader_message != '') { ?>
<div class="alert alert-dark" role="alert">
<?php echo $file_uploader_message; ?>
</div>
<?php } ?>

<div class="card filesmanager">
<div class="card-header">
<div class="row">
Expand Down

0 comments on commit 2631943

Please sign in to comment.