보안 업로드 스크립트

Aug 17 2020

사용자가 프로필 사진을 업로드 할 수있는 소셜 네트워크를 만들고 있습니다. 이것이 안전한 방법인지 알고 싶습니다. 감사.

<?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 Aug 18 2020 at 21:13

이것은 내 개인적인 의견이지만 다음과 같이 말하고 싶습니다.

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

나는 이것이 어떤 식 으로든 도움이되기를 바랍니다 :)