-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathb.php
More file actions
100 lines (88 loc) · 3.05 KB
/
b.php
File metadata and controls
100 lines (88 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
$baseDir = realpath(__DIR__ . '/static/banners') ?: (__DIR__ . '/static/banners');
$dir = $baseDir;
if (isset($_GET['board']) && is_string($_GET['board'])) {
$board = trim($_GET['board']);
$board = trim($board, "\t\n\r\0\x0B/\\");
if ($board !== '' && preg_match('/^[A-Za-z0-9_-]+$/', $board)) {
$candidate = $baseDir . DIRECTORY_SEPARATOR . $board;
$real = realpath($candidate);
$baseReal = realpath($baseDir) ?: $baseDir;
if ($real !== false && is_dir($real) && str_starts_with($real, $baseReal . DIRECTORY_SEPARATOR)) {
$dir = $real;
}
}
}
$allowedExtensions = ['gif', 'jpg', 'jpeg', 'png', 'webp', 'svg', 'apng'];
$entries = @scandir($dir, SCANDIR_SORT_NONE) ?: [];
$images = [];
foreach ($entries as $file) {
if ($file === '.' || $file === '..' || $file === '' || $file[0] === '.') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (!is_file($path)) {
continue;
}
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (in_array($ext, $allowedExtensions, true)) {
$images[] = $file;
}
}
if (!$images) {
http_response_code(404);
header('Content-Type: text/plain; charset=UTF-8');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
echo 'No banners available';
exit;
}
$selected = $images[array_rand($images)];
$path = $dir . DIRECTORY_SEPARATOR . $selected;
$finfo = function_exists('finfo_open') ? finfo_open(FILEINFO_MIME_TYPE) : false;
$type = $finfo ? finfo_file($finfo, $path) : null;
if ($finfo) {
finfo_close($finfo);
}
if (!$type) {
$ext = strtolower(pathinfo($selected, PATHINFO_EXTENSION));
$map = [
'gif' => 'image/gif',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'webp' => 'image/webp',
'svg' => 'image/svg+xml',
'apng' => 'image/apng',
];
$type = $map[$ext] ?? 'application/octet-stream';
}
$bytes = filesize($path);
$lastModified = gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT';
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header("Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'");
header('Referrer-Policy: no-referrer');
header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
header('Cross-Origin-Resource-Policy: same-origin');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
header('Content-Type: ' . $type);
header('Content-Length: ' . $bytes);
header('Last-Modified: ' . $lastModified);
$filename = basename($selected);
header('Content-Disposition: inline; filename="' . rawurlencode($filename) . '"');
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'HEAD') {
exit;
}
$fp = fopen($path, 'rb');
if ($fp === false) {
http_response_code(500);
header('Content-Type: text/plain; charset=UTF-8');
echo 'Failed to open banner';
exit;
}
fpassthru($fp);
fclose($fp);