mirror of
https://github.com/sbrl/Pepperminty-Wiki.git
synced 2024-11-24 17:13:01 +00:00
feature-upload: fix potential XSS attacks
This commit is contained in:
parent
4a00a404e1
commit
227a7ac662
2 changed files with 19 additions and 19 deletions
|
@ -14,7 +14,7 @@ $env = new stdClass();
|
||||||
$env->action = $settings->defaultaction;
|
$env->action = $settings->defaultaction;
|
||||||
/** The page name requested by the remote client. @var string */
|
/** The page name requested by the remote client. @var string */
|
||||||
$env->page = "";
|
$env->page = "";
|
||||||
/** The page name, but run through htmlentities(), thus making it safe to display in an output document. */
|
/** The page name, but run through htmlentities(), thus making it safe to display in an output document. @var string */
|
||||||
$env->page_safe = "";
|
$env->page_safe = "";
|
||||||
/** The filename that the page is stored in. @var string */
|
/** The filename that the page is stored in. @var string */
|
||||||
$env->page_filename = "";
|
$env->page_filename = "";
|
||||||
|
|
|
@ -65,7 +65,7 @@ register_module([
|
||||||
|
|
||||||
if($is_avatar) {
|
if($is_avatar) {
|
||||||
exit(page_renderer::render("Upload avatar - $settings->sitename", "<h1>Upload avatar</h1>
|
exit(page_renderer::render("Upload avatar - $settings->sitename", "<h1>Upload avatar</h1>
|
||||||
<p>Select an image below, and then press upload. $settings->sitename currently supports the following file types (though not all of them may be suitable for an avatar): " . implode(", ", $settings->upload_allowed_file_types) . "</p>
|
<p>Select an image below, and then press upload. $settings->sitename currently supports the following file types (though not all of them may be suitable for an avatar): " . htmlentities(implode(", ", $settings->upload_allowed_file_types)) . "</p>
|
||||||
<form method='post' action='?action=upload' enctype='multipart/form-data'>
|
<form method='post' action='?action=upload' enctype='multipart/form-data'>
|
||||||
<label for='file'>Select a file to upload.</label>
|
<label for='file'>Select a file to upload.</label>
|
||||||
<input type='file' name='file' id='file-upload-selector' tabindex='1' />
|
<input type='file' name='file' id='file-upload-selector' tabindex='1' />
|
||||||
|
@ -106,7 +106,7 @@ register_module([
|
||||||
// Receive file
|
// Receive file
|
||||||
|
|
||||||
if(!$settings->editing) {
|
if(!$settings->editing) {
|
||||||
exit(page_renderer::render_main("Upload failed - $settings->sitename", "<p>Your upload couldn't be processed because editing is currently disabled on $settings->sitename. Please contact $settings->admindetails_name, $settings->sitename's administrator for more information - their contact details can be found at the bottom of this page. <a href='index.php'>Go back to the main page</a>."));
|
exit(page_renderer::render_main("Upload failed - $settings->sitename", "<p>Your upload couldn't be processed because editing is currently disabled on $settings->sitename. Please contact ".htmlentities($settings->admindetails_name).", $settings->sitename's administrator for more information - their contact details can be found at the bottom of this page. <a href='index.php'>Go back to the main page</a>."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure uploads are enabled
|
// Make sure uploads are enabled
|
||||||
|
@ -136,13 +136,13 @@ register_module([
|
||||||
http_response_code(413); // file is too large
|
http_response_code(413); // file is too large
|
||||||
else
|
else
|
||||||
http_response_code(500); // something else went wrong
|
http_response_code(500); // something else went wrong
|
||||||
exit(page_renderer::render("Upload failed - $settings->sitename", "<p>Your upload couldn't be processed because " . (($_FILES["file"]["error"] == 1 || $_FILES["file"]["error"] == 2) ? "the file is too large" : "an error occurred") . ".</p><p>Please contact $settings->admindetails_name, $settings->sitename's administrator for help.</p>"));
|
exit(page_renderer::render("Upload failed - $settings->sitename", "<p>Your upload couldn't be processed because " . (($_FILES["file"]["error"] == 1 || $_FILES["file"]["error"] == 2) ? "the file is too large" : "an error occurred") . ".</p><p>Please contact ".htmlentities($settings->admindetails_name).", $settings->sitename's administrator for help.</p>"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!function_exists("finfo_file")) {
|
if(!function_exists("finfo_file")) {
|
||||||
http_response_code(503);
|
http_response_code(503);
|
||||||
exit(page_renderer::render("Upload failed - Server error - $settings->sitename", "<p>Your upload couldn't be processed because <code>fileinfo</code> is not installed on the server. This is required to properly check the file type of uploaded files.</p>><p>Please contact $settings->admindetails_name, $settings->sitename's administrator for help.</p>"));
|
exit(page_renderer::render("Upload failed - Server error - $settings->sitename", "<p>Your upload couldn't be processed because <code>fileinfo</code> is not installed on the server. This is required to properly check the file type of uploaded files.</p>><p>Please contact ".htmlentities($settings->admindetails_name).", $settings->sitename's administrator for help.</p>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the target name, removing any characters we
|
// Calculate the target name, removing any characters we
|
||||||
|
@ -159,14 +159,14 @@ register_module([
|
||||||
{
|
{
|
||||||
http_response_code(415);
|
http_response_code(415);
|
||||||
exit(page_renderer::render("Unknown file type - Upload error - $settings->sitename", "<p>$settings->sitename recieved the file you tried to upload successfully, but detected that the type of file you uploaded is not in the allowed file types list. The file has been discarded.</p>
|
exit(page_renderer::render("Unknown file type - Upload error - $settings->sitename", "<p>$settings->sitename recieved the file you tried to upload successfully, but detected that the type of file you uploaded is not in the allowed file types list. The file has been discarded.</p>
|
||||||
<p>The file you tried to upload appeared to be of type <code>$mime_type</code>, but $settings->sitename currently only allows the uploading of the following file types: <code>" . implode("</code>, <code>", $settings->upload_allowed_file_types) . "</code>.</p>
|
<p>The file you tried to upload appeared to be of type <code>$mime_type</code>, but $settings->sitename currently only allows the uploading of the following file types: <code>" . htmlentities(implode("</code>, <code>", $settings->upload_allowed_file_types)) . "</code>.</p>
|
||||||
<p><a href='?action=$settings->defaultaction'>Go back</a> to the Main Page.</p>"));
|
<p><a href='?action=$settings->defaultaction'>Go back</a> to the Main Page.</p>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform appropriate checks based on the *real* filetype
|
// Perform appropriate checks based on the *real* filetype
|
||||||
if($is_avatar && substr($mime_type, 0, strpos($mime_type, "/")) !== "image") {
|
if($is_avatar && substr($mime_type, 0, strpos($mime_type, "/")) !== "image") {
|
||||||
http_response_code(415);
|
http_response_code(415);
|
||||||
exit(page_renderer::render_main("Error uploading avatar - $settings->sitename", "<p>That file appears to be unsuitable as an avatar, as $settings->sitename has detected it to be of type <code>$mime_type</code>, which doesn't appear to be an image. Please try <a href='?action=upload&avatar=yes'>uploading a different file</a> to use as your avatar.</p>"));
|
exit(page_renderer::render_main("Error uploading avatar - $settings->sitename", "<p>That file appears to be unsuitable as an avatar, as $settings->sitename has detected it to be of type <code>".htmlentities($mime_type)."</code>, which doesn't appear to be an image. Please try <a href='?action=upload&avatar=yes'>uploading a different file</a> to use as your avatar.</p>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(substr($mime_type, 0, strpos($mime_type, "/")))
|
switch(substr($mime_type, 0, strpos($mime_type, "/")))
|
||||||
|
@ -197,7 +197,7 @@ register_module([
|
||||||
{
|
{
|
||||||
http_response_code(415);
|
http_response_code(415);
|
||||||
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>The file you uploaded appears to be dangerous and has been discarded. Please contact $settings->sitename's administrator for assistance.</p>
|
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>The file you uploaded appears to be dangerous and has been discarded. Please contact $settings->sitename's administrator for assistance.</p>
|
||||||
<p>Additional information: The file uploaded appeared to be of type <code>$mime_type</code>, which mapped onto the extension <code>$file_extension</code>. This file extension has the potential to be executed accidentally by the web server.</p>"));
|
<p>Additional information: The file uploaded appeared to be of type <code>".htmlentities($mime_type)."</code>, which mapped onto the extension <code>".htmlentities($file_extension)."</code>. This file extension has the potential to be executed accidentally by the web server.</p>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove dots from both ends, just in case
|
// Remove dots from both ends, just in case
|
||||||
|
@ -221,7 +221,7 @@ register_module([
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($pageindex->$new_pagepath) && !$is_avatar)
|
if(isset($pageindex->$new_pagepath) && !$is_avatar)
|
||||||
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>A page or file has already been uploaded with the name '$new_filename'. Try deleting it first. If you do not have permission to delete things, try contacting one of the moderators.</p>"));
|
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>A page or file has already been uploaded with the name '".htmlentities($new_filename)."'. Try deleting it first. If you do not have permission to delete things, try contacting one of the moderators.</p>"));
|
||||||
|
|
||||||
// Delete the previously uploaded avatar, if it exists
|
// Delete the previously uploaded avatar, if it exists
|
||||||
// In the future we _may_ not need this once we have
|
// In the future we _may_ not need this once we have
|
||||||
|
@ -236,7 +236,7 @@ register_module([
|
||||||
if(!move_uploaded_file($temp_filename, $env->storage_prefix . $new_filename))
|
if(!move_uploaded_file($temp_filename, $env->storage_prefix . $new_filename))
|
||||||
{
|
{
|
||||||
http_response_code(409);
|
http_response_code(409);
|
||||||
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>The file you uploaded was valid, but $settings->sitename couldn't verify that it was tampered with during the upload process. This probably means that either is a configuration error, or that $settings->sitename has been attacked. Please contact " . $settings->admindetails_name . ", your $settings->sitename Administrator.</p>"));
|
exit(page_renderer::render("Upload Error - $settings->sitename", "<p>The file you uploaded was valid, but $settings->sitename couldn't verify that it was tampered with during the upload process. This probably means that either is a configuration error, or that $settings->sitename has been attacked. Please contact ".htmlentities($settings->admindetails_name).", your $settings->sitename Administrator.</p>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
$description = $_POST["description"] ?? "_(No description provided)_\n";
|
$description = $_POST["description"] ?? "_(No description provided)_\n";
|
||||||
|
@ -284,7 +284,7 @@ register_module([
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
header("location: ?action=view&page=$new_pagepath&upload=success");
|
header("location: ?action=view&page=".rawurlencode($new_pagepath)."&upload=success");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ register_module([
|
||||||
|
|
||||||
if(empty($pageindex->{$env->page}->uploadedfilepath))
|
if(empty($pageindex->{$env->page}->uploadedfilepath))
|
||||||
{
|
{
|
||||||
$im = errorimage("The page '$env->page' doesn't have an associated file.");
|
$im = errorimage("The page '$env->page_safe' doesn't have an associated file.");
|
||||||
header("content-type: image/png");
|
header("content-type: image/png");
|
||||||
imagepng($im);
|
imagepng($im);
|
||||||
exit();
|
exit();
|
||||||
|
@ -323,7 +323,7 @@ register_module([
|
||||||
|
|
||||||
$filepath = realpath($env->storage_prefix . $pageindex->{$env->page}->uploadedfilepath);
|
$filepath = realpath($env->storage_prefix . $pageindex->{$env->page}->uploadedfilepath);
|
||||||
$mime_type = $pageindex->{$env->page}->uploadedfilemime;
|
$mime_type = $pageindex->{$env->page}->uploadedfilemime;
|
||||||
$shortFilename = substr($filepath, 1 + (strrpos($filepath, '/') !== false ? strrpos($filepath, '/') : -1));
|
$shortFilename = str_replace(["\r", "\n", "\""], "", substr($filepath, 1 + (strrpos($filepath, '/') !== false ? strrpos($filepath, '/') : -1)));
|
||||||
|
|
||||||
header("content-disposition: inline; filename=\"$shortFilename\"");
|
header("content-disposition: inline; filename=\"$shortFilename\"");
|
||||||
header("last-modified: " . gmdate('D, d M Y H:i:s T', $pageindex->{$env->page}->lastmodified));
|
header("last-modified: " . gmdate('D, d M Y H:i:s T', $pageindex->{$env->page}->lastmodified));
|
||||||
|
@ -485,9 +485,9 @@ register_module([
|
||||||
$filepath = $pageindex->{$env->page}->uploadedfilepath;
|
$filepath = $pageindex->{$env->page}->uploadedfilepath;
|
||||||
$mime_type = $pageindex->{$env->page}->uploadedfilemime;
|
$mime_type = $pageindex->{$env->page}->uploadedfilemime;
|
||||||
$dimensions = $mime_type !== "image/svg+xml" ? getimagesize($env->storage_prefix . $filepath) : getsvgsize($env->storage_prefix . $filepath);
|
$dimensions = $mime_type !== "image/svg+xml" ? getimagesize($env->storage_prefix . $filepath) : getsvgsize($env->storage_prefix . $filepath);
|
||||||
$fileTypeDisplay = substr($mime_type, 0, strpos($mime_type, "/"));
|
$fileTypeDisplay = slugify(substr($mime_type, 0, strpos($mime_type, "/")));
|
||||||
$previewUrl = "?action=preview&size=$settings->default_preview_size&page=" . rawurlencode($env->page);
|
$previewUrl = htmlentities("?action=preview&size=$settings->default_preview_size&page=" . rawurlencode($env->page));
|
||||||
$originalUrl = $env->storage_prefix == "./" ? $filepath : "?action=preview&size=original&page=" . rawurlencode($env->page);
|
$originalUrl = htmlentities($env->storage_prefix == "./" ? $filepath : "?action=preview&size=original&page=" . rawurlencode($env->page));
|
||||||
if($mime_type == "application/pdf")
|
if($mime_type == "application/pdf")
|
||||||
$fileTypeDisplay = "pdf";
|
$fileTypeDisplay = "pdf";
|
||||||
|
|
||||||
|
@ -534,8 +534,8 @@ register_module([
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileInfo = [];
|
$fileInfo = [];
|
||||||
$fileInfo["Name"] = str_replace("Files/", "", $filepath);
|
$fileInfo["Name"] = htmlentities(str_replace("Files/", "", $filepath));
|
||||||
$fileInfo["Type"] = $mime_type;
|
$fileInfo["Type"] = htmlentities($mime_type);
|
||||||
$fileInfo["Size"] = human_filesize(filesize($env->storage_prefix . $filepath));
|
$fileInfo["Size"] = human_filesize(filesize($env->storage_prefix . $filepath));
|
||||||
switch($fileTypeDisplay)
|
switch($fileTypeDisplay)
|
||||||
{
|
{
|
||||||
|
@ -551,7 +551,7 @@ register_module([
|
||||||
<table>";
|
<table>";
|
||||||
foreach ($fileInfo as $displayName => $displayValue)
|
foreach ($fileInfo as $displayName => $displayValue)
|
||||||
{
|
{
|
||||||
$preview_html .= "<tr><th>$displayName</th><td>$displayValue</td></tr>\n";
|
$preview_html .= "<tr><th>".htmlentities($displayName)."</th><td>$displayValue</td></tr>\n";
|
||||||
}
|
}
|
||||||
$preview_html .= "</table>";
|
$preview_html .= "</table>";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue