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:
@@ -350,3 +350,51 @@ function which_table($move = FALSE, $action = 'read') {
|
||||
return 'xxx';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Uploaded images wait in a directory outside the web root until the
|
||||
* story is saved. The session holds the random file name, so the client
|
||||
* never sends a file path.
|
||||
*/
|
||||
function upload_dir() {
|
||||
$dir = rtrim(config('UPLOAD_DIR') ?: sys_get_temp_dir() . '/xxx-uploads', '/');
|
||||
if (!is_dir($dir))
|
||||
mkdir($dir, 0700, TRUE);
|
||||
return $dir;
|
||||
}
|
||||
|
||||
function is_upload_name($name) {
|
||||
return is_string($name) && preg_match('/^[0-9a-f]{32}$/', $name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move a file from $_FILES into the upload directory, and remember it
|
||||
* in the session. Returns the new path, or FALSE.
|
||||
*/
|
||||
function store_upload($tmp_file) {
|
||||
$name = bin2hex(random_bytes(16));
|
||||
$file = upload_dir() . '/' . $name;
|
||||
if (!move_uploaded_file($tmp_file, $file))
|
||||
return FALSE;
|
||||
$_SESSION['pending_upload'] = $name;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the path of the image this session uploaded earlier, or FALSE.
|
||||
*/
|
||||
function pending_upload() {
|
||||
$name = $_SESSION['pending_upload'] ?? NULL;
|
||||
if (!is_upload_name($name))
|
||||
return FALSE;
|
||||
$file = upload_dir() . '/' . $name;
|
||||
return is_file($file) ? $file : FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* URL that shows the pending image; the name part stops browsers from
|
||||
* showing an older upload from their cache.
|
||||
*/
|
||||
function pending_upload_url() {
|
||||
return '/display?pending=' . substr($_SESSION['pending_upload'] ?? '', 0, 8);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user