Tập lệnh tải lên an toàn
Aug 17 2020
Tôi đang tạo một mạng xã hội cho phép người dùng tải lên ảnh hồ sơ. Tôi chỉ muốn biết liệu đây có phải là một cách làm an toàn hay không. Cảm ơn.
<?php
include 'includes/header.php';
include 'includes/form_handlers/settings_handler.php';
//$userPic = ''; $date_time = date('Y-m-d_H-i-s');
if(!empty($userLoggedIn)) { if (isset($_FILES['fileToUpload'])) {
$errors= array(); $file_name = $_FILES['fileToUpload']['name']; $file_size = $_FILES['fileToUpload']['size']; $width = 1500;
$height = 1500; $file_tmp = $_FILES['fileToUpload']['tmp_name']; $file_type = $_FILES['fileToUpload']['type']; $tmp = explode('.',$_FILES['fileToUpload']['name']); $file_ext=strtolower (end ($tmp)); $extensions = array( "jpeg", "jpg", "png", "gif");
if(in_array($file_ext,$extensions)=== false){
$errors[]="extension not allowed, please choose a JPEG or PNG file."; } if ($file_size > 8097152) {
$errors[] = 'File size must be 2 MB'; } if ($width > 1500 || $height > 1500) { echo"File is to large"; } if(!$errors) {
$userPic = md5($_FILES["fileToUpload"]["name"]) . $date_time . " " . $file_name;
$profilePic = move_uploaded_file($file_tmp,"assets/images/profile_pics/" . $userPic); $file_path = "assets/images/profile_pics/" . $userPic; $stmt = $con->prepare("UPDATE users SET profile_pic = ? WHERE username = ?"); $stmt->bind_param('ss', $file_path, $username);
$stmt->execute(); $stmt->close();
header('Location: settings.php');
exit();
}
}
} else {
echo "Invalid Username";
}
?>
Trả lời
5 LiamSorsby Aug 18 2020 at 21:13
Đây là ý kiến cá nhân của tôi, nhưng tôi sẽ nói như sau:
- Mã phải được định dạng, cá nhân tôi muốn xem xét PSR-12 vì tiêu chuẩn này nên được tuân theo khi có thể.
- move_uploaded_file không bảo vệ chống lại việc duyệt qua thư mục. Bạn nên sử dụng tên cơ sở trên
$_FILES['fileToUpload']['tmp_name']và một số hình thức xác thực khác - Việc kiểm tra phần mở rộng của tệp
if(in_array($file_ext,$extensions)=== false)không ngăn người dùng tải lên tệp độc hại, chẳng hạn như họ có thể sử dụng một byte ma thuật để đánh lừa máy chủ nghĩ rằng đó là một loại tệp nhất định. Bạn nên xem qua finfo và ví dụ đầu tiên về tải lên tệp - Bạn đang tạo ra một loạt các lỗi, hiện đang được kiểm tra trong câu lệnh if và sau đó bị loại bỏ. Nếu bạn không có kế hoạch sử dụng nó, bạn có thể nên quay lại sớm khỏi chức năng hơn là tiếp tục thực hiện.
- Tùy thuộc vào mức độ độc đáo của tên tệp, bạn có thể muốn sử dụng một cái gì đó như
uniqid(mt_rand(), true) - move_uploaded_file sẽ thay thế một tệp nếu nó đã tồn tại, bạn có thể muốn kiểm tra xem tệp này có tồn tại hay không trước khi ghi đè lên tệp hiện có. Tùy thuộc vào giải pháp đặt tên của bạn, điều này rất khó xảy ra nhưng dưới tải cao trong thời gian dài, điều này có thể xảy ra thường xuyên hơn bạn nghĩ.
- Bạn đang sử dụng,
UPDATE users SET profile_pic = ? WHERE username = ?tôi giả sử rằng giá trị này tồn tại trong cơ sở dữ liệu vì người dùng cần đăng nhập. Tuy nhiên, nếu bạn không chắc liệu trường có tồn tại hay không (tôi chưa thấy cơ sở dữ liệu), tôi sẽ sử dụng cá nhân:INSERT INTO users (profile_pic, username) VALUES (?,?) ON DUPLICATE KEY UPDATE profile_pic=?, username=?điều này sẽ chèn vào bảng nếu hàng không tồn tại nhưng sẽ cập nhật nó nếu có. - Bạn đã đặt một biến cục bộ có tên là chiều rộng và chiều cao và đang so sánh chúng với cùng một giá trị. Tôi cho rằng điều này nhằm mục đích kiểm tra kích thước tệp thực tế?
Tôi hy vọng việc này sẽ có ích trong vài trường hợp :)