summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-06-04 21:02:51 +0400
committerilotterytea <iltsu@alright.party>2025-06-04 21:02:51 +0400
commitd59e9b569fb828cdb145a3497c1b1f9e27cd03ad (patch)
treef4f96c76ec2b6cc9a3aa42aba5efbf213b589143
parent28658d12a464777b50c789c2e9c3f86ce8f07da0 (diff)
feat: verify file mime type
-rw-r--r--lib/file.php37
-rw-r--r--public/delete.php14
-rw-r--r--public/upload.php26
3 files changed, 61 insertions, 16 deletions
diff --git a/lib/file.php b/lib/file.php
new file mode 100644
index 0000000..4fcb607
--- /dev/null
+++ b/lib/file.php
@@ -0,0 +1,37 @@
+<?php
+include_once $_SERVER['DOCUMENT_ROOT'] . '/../config.php';
+
+function verify_mimetype(string $file_path, string $mimetype): bool
+{
+ $path = escapeshellarg($file_path);
+
+ if (str_starts_with($mimetype, 'image/')) {
+ $output = shell_exec("identify -quiet -ping $path");
+ return !empty($output);
+ } else if (str_starts_with($mimetype, 'video/') || str_starts_with($mimetype, 'audio/')) {
+ $output = [];
+ $exitCode = 0;
+ $cmd = 'ffprobe -v error -i "/path/to/video.mp4" 2>&1';
+ exec($cmd, $output, $exitCode);
+ return $exitCode === 0;
+ }
+
+ throw new RuntimeException("Illegal type for MIME verifications: $mimetype");
+}
+
+function delete_file(string $file_id, string $file_extension): bool
+{
+ $paths = [
+ FILE_UPLOAD_DIRECTORY . "/{$file_id}.{$file_extension}",
+ FILE_THUMBNAIL_DIRECTORY . "/{$file_id}.webp",
+ FILE_METADATA_DIRECTORY . "/{$file_id}.metadata.json"
+ ];
+
+ foreach ($paths as $path) {
+ if (is_file($path) && !unlink($path)) {
+ return false;
+ }
+ }
+
+ return true;
+} \ No newline at end of file
diff --git a/public/delete.php b/public/delete.php
index 26d91aa..b716796 100644
--- a/public/delete.php
+++ b/public/delete.php
@@ -46,17 +46,9 @@ if (!password_verify($password, $metadata['password'])) {
exit();
}
-$paths = [
- FILE_UPLOAD_DIRECTORY . "/{$file_id}.{$file_ext}",
- FILE_THUMBNAIL_DIRECTORY . "/{$file_id}.webp",
- FILE_METADATA_DIRECTORY . "/{$file_id}.metadata.json"
-];
-
-foreach ($paths as $path) {
- if (is_file($path) && !unlink($path)) {
- json_response(null, "Failed to delete a file ID {$file_id}", 500);
- exit();
- }
+if (!delete_file($file_id, $file_ext)) {
+ json_response(null, 'Failed to remove files. Try again later.', 500);
+ exit();
}
json_response(
diff --git a/public/upload.php b/public/upload.php
index 0d8a7e3..31822ba 100644
--- a/public/upload.php
+++ b/public/upload.php
@@ -2,6 +2,7 @@
include_once $_SERVER['DOCUMENT_ROOT'] . '/../config.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/utils.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/thumbnails.php';
+include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/file.php';
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
json_response(null, 'Method not allowed', 405);
@@ -83,9 +84,16 @@ try {
throw new RuntimeException("Invalid file format.");
}
+ // verifying file mimetype
+ $file_mime = FILE_ACCEPTED_MIME_TYPES[$file_ext];
+ $is_media = str_starts_with($file_mime, 'image/') || str_starts_with($file_mime, 'video/') || str_starts_with($file_mime, 'audio/');
+ if (FILE_VERIFY_MIMETYPE && $is_media && !verify_mimetype($file['tmp_name'], $file_mime)) {
+ throw new RuntimeException('Invalid file format.');
+ }
+
$file_data = [
'size' => $file['size'],
- 'mime' => FILE_ACCEPTED_MIME_TYPES[$file_ext],
+ 'mime' => $file_mime,
'extension' => $file_ext
];
}
@@ -110,11 +118,11 @@ try {
$result = 0;
$output = [];
+ $file_path = FILE_UPLOAD_DIRECTORY . "/$file_id.{$file_data['extension']}";
+
exec(sprintf(
- 'yt-dlp -f "worst" -o "%s/%s.%s" %s 2>&1',
- FILE_UPLOAD_DIRECTORY,
- $file_id,
- $file_data['extension'],
+ 'yt-dlp -f "worst" -o "%s" %s 2>&1',
+ $file_path,
escapeshellarg($url)
), $output, $result);
@@ -122,6 +130,14 @@ try {
error_log(sprintf("Failed to download a file (URL: %s): %s", $url, implode('\n', $output)));
throw new RuntimeException('Failed to download a file! Try again later.');
}
+
+ // verifying file mime type
+ $file_mime = $file_data['mime'];
+ $is_media = str_starts_with($file_mime, 'image/') || str_starts_with($file_mime, 'video/') || str_starts_with($file_mime, 'audio/');
+ if (FILE_VERIFY_MIMETYPE && $is_media && !verify_mimetype($file_path, $file_mime)) {
+ delete_file($file_id, $file_data['extension']);
+ throw new RuntimeException('Invalid file format.');
+ }
} else if (isset($paste) && !file_put_contents(FILE_UPLOAD_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']), $paste)) {
throw new RuntimeException('Failed to paste a text! Try again later.');
} else if (isset($file) && !move_uploaded_file($file['tmp_name'], FILE_UPLOAD_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']))) {