보안 업로드 스크립트
사용자가 프로필 사진을 업로드 할 수있는 소셜 네트워크를 만들고 있습니다. 이것이 안전한 방법인지 알고 싶습니다. 감사.
<?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";
}
?>
답변
5 LiamSorsby
이것은 내 개인적인 의견이지만 다음과 같이 말하고 싶습니다.
- 코드는 형식이 지정 되어야합니다. 가능하면이 표준을 따라야하므로 개인적으로 PSR-12 를 살펴 보겠습니다 .
- move_uploaded_file은 디렉토리 순회로부터 보호하지 않습니다. basename on
$_FILES['fileToUpload']['tmp_name']
및 다른 형식의 유효성 검사를 사용해야 합니다. - 파일 확장자를 확인
if(in_array($file_ext,$extensions)=== false)
한다고해서 사용자가 악성 파일을 업로드하는 것을 방지 할 수는 없습니다. 예를 들어 매직 바이트를 사용하여 서버가 특정 유형의 파일이라고 생각하도록 속일 수 있습니다. finfo 와 파일 업로드 에 대한 첫 번째 예를 살펴보아야 합니다. - 현재 if 문에서 확인되고있는 오류 배열을 만든 다음 버려집니다. 사용할 계획이 없다면 실행을 계속하는 것보다 일찍 함수에서 빠져 나가는 것이 좋습니다.
- 파일 이름이 얼마나 고유해야하는지에 따라 다음과 같이 사용할 수 있습니다.
uniqid(mt_rand(), true)
- move_uploaded_file은 이미 존재하는 파일을 대체합니다. 기존 파일을 덮어 쓰기 전에 이것이 존재하는지 확인할 수 있습니다. 이름 지정 솔루션에 따라 발생할 가능성은 거의 없지만 오랜 시간 동안 높은 부하를 받으면 생각보다 더 자주 발생할 수 있습니다.
- 사용자가
UPDATE users SET profile_pic = ? WHERE username = ?
로그인해야하므로이 값이 데이터베이스에 있다고 가정합니다. 그러나 필드가 있는지 여부가 확실하지 않은 경우 (데이터베이스를 보지 못함) 개인적으로 사용 :INSERT INTO users (profile_pic, username) VALUES (?,?) ON DUPLICATE KEY UPDATE profile_pic=?, username=?
행이 존재하지 않으면 테이블에 삽입되지만 존재하는 경우 업데이트합니다. - 너비와 높이라는 지역 변수를 설정하고 동일한 값과 비교하고 있습니다. 이것이 실제 파일 크기를 확인하기위한 것이라고 생각합니까?
나는 이것이 어떤 식 으로든 도움이되기를 바랍니다 :)