Keep uploads outside the web root.

save_uploaded_file() read, and prune_images() deleted, any path in the
"uploaded" POST field. Uploads now go to UPLOAD_DIR under a random name
that only the session knows.
This commit is contained in:
tim
2026-09-25 21:31:47 +02:00
parent c85f54116c
commit e881ddb458
7 changed files with 104 additions and 41 deletions
+7 -1
View File
@@ -1,4 +1,10 @@
<?php require_once("../session.lib.php"); ?>
<?php
if ( ! isset($_SERVER['HTTPS'])) {
header('Location: https://' . $_SERVER["SERVER_NAME"] . $_SERVER['REQUEST_URI']);
exit;
}
require_once("../session.lib.php");
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
+18 -30
View File
@@ -152,44 +152,32 @@ function get_mimetype($image_file) {
}
function save_uploaded_file() {
// Save uploaded file to new, temporary location
// A new upload in this request
if (is_uploaded_file($_FILES['upload']['tmp_name'] ?? '')) {
$tmp_file = $_FILES['upload']['tmp_name'];
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/graphics" . $tmp_file;
$end_dir = dirname($new_file);
if (!is_dir($end_dir))
mkdir($end_dir, "0644", 1);
$image_file = $new_file;
move_uploaded_file($tmp_file, $image_file);
// File has already been uploaded, get location
} else if (isset($_POST['uploaded']) &&
is_file($_SERVER['DOCUMENT_ROOT'] . $_POST['uploaded'])) {
$image_file = realpath($_SERVER['DOCUMENT_ROOT'] . $_POST['uploaded']);
return store_upload($_FILES['upload']['tmp_name']);
}
if (isset($image_file)) {
return $image_file;
} else {
return FALSE;
// An image uploaded at the preview step; the session knows which one
if (($_POST['uploaded'] ?? '') === 'pending') {
return pending_upload();
}
return FALSE;
}
function prune_images($image_file) {
// Delete image from filesystem, and cleanup anything older than $age
$age = '86400'; // a day old
$cleanup_dir = dirname($image_file);
unlink($image_file);
// Delete the saved image, and anything older than $age.
// Only ever touch upload files inside the upload directory.
$age = 86400; // a day old
$dir = upload_dir();
if (dirname($image_file) === $dir && is_upload_name(basename($image_file))) {
@unlink($image_file);
}
unset($_SESSION['pending_upload']);
if ( $dir_handle = @opendir($cleanup_dir) ) {
while (($cleanup_file = readdir ($dir_handle)) !== FALSE) {
if ($cleanup_file == '.' || $cleanup_file == '..') continue;
$cleanup_file = $cleanup_dir . "/". $cleanup_file;
if (@filemtime($cleanup_file) < (time() - $age)) {
@unlink($cleanup_file);
}
foreach (glob($dir . '/*') as $cleanup_file) {
if (is_upload_name(basename($cleanup_file)) &&
@filemtime($cleanup_file) < (time() - $age)) {
@unlink($cleanup_file);
}
closedir($dir_handle);
}
}
+7 -8
View File
@@ -23,14 +23,13 @@ if (isset($_POST['g-recaptcha-response'])) {
echo '<p>Please review your submission. Once you\'ve finished, please click "Submit" at the bottom of the page, or click "Preview" to check it again.</p>';
if (is_uploaded_file($_FILES['upload']['tmp_name'] ?? '') &&!isset($validate['upload'])) {
$tmp_file = $_FILES['upload']['tmp_name'];
$upload = getimagesize($tmp_file);
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/graphics" . $tmp_file;
move_uploaded_file($tmp_file, $new_file);
$file_src = "/graphics" .$tmp_file;
} else if (isset($uploaded) && is_file($_SERVER['DOCUMENT_ROOT'] . $uploaded) && !$remove_img) {
$file_src = $uploaded;
// Keep a new image outside the web root until the story is saved;
// display.php shows it to this session only.
if (is_uploaded_file($_FILES['upload']['tmp_name'] ?? '') && !isset($validate['upload'])) {
if (store_upload($_FILES['upload']['tmp_name']))
$file_src = pending_upload_url();
} else if (isset($uploaded) && $uploaded === 'pending' && pending_upload() && !$remove_img) {
$file_src = pending_upload_url();
}
echo display_stories();
+1 -1
View File
@@ -60,7 +60,7 @@ echo (isset($story) ? $story : '')
<?php
if (isset($file_src) || isset($img)) {
if (isset($file_src)) {
echo ' <input type="hidden" id="uploaded" name="uploaded" value="'.$file_src.'" />';
echo ' <input type="hidden" id="uploaded" name="uploaded" value="pending" />';
} else {
echo ' <input type="hidden" id="uploaded" name="uploaded" value="'.$id.'" />';
}