programing

PHP 이미지 업로드 보안 확인 목록

lastcode 2023. 7. 31. 21:25
반응형

PHP 이미지 업로드 보안 확인 목록

나는 내 애플리케이션에 이미지를 업로드하기 위해 스크립트를 프로그래밍하고 있습니다.다음 보안 단계는 스크립트 측에서 응용 프로그램을 안전하게 보호하기에 충분합니까?

  • .httaccess를 사용하여 업로드 폴더 내에서 PHP가 실행되지 않도록 설정합니다.
  • 파일 이름에 "php" 문자열이 포함된 경우 업로드를 허용하지 않습니다.
  • 확장자 jpg, jpeg, gif 및 png만 허용합니다.
  • 이미지 파일 형식만 허용합니다.
  • 두 개의 파일 형식을 가진 이미지를 허용하지 않습니다.
  • 이미지 이름을 변경합니다.
  • 루트 디렉터리가 아닌 하위 디렉터리로 업로드합니다.

내 대본은 다음과 같습니다.

 $filename=$_FILES['my_files']['name'];
 $filetype=$_FILES['my_files']['type'];
 $filename = strtolower($filename);
 $filetype = strtolower($filetype);

 //check if contain php and kill it 
 $pos = strpos($filename,'php');
 if(!($pos === false)) {
  die('error');
 }




 //get the file ext

 $file_ext = strrchr($filename, '.');


 //check if its allowed or not
 $whitelist = array(".jpg",".jpeg",".gif",".png"); 
 if (!(in_array($file_ext, $whitelist))) {
    die('not allowed extension,please upload images only');
 }


 //check upload type
 $pos = strpos($filetype,'image');
 if($pos === false) {
  die('error 1');
 }
 $imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
 if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime']      != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
   die('error 2');
 }
//check double file type (image with comment)
if(substr_count($filetype, '/')>1){
die('error 3')
}

 // upload to upload direcory 
 $uploaddir = 'upload/'.date("Y-m-d").'/' ;

if (file_exists($uploaddir)) {  
} else {  
    mkdir( $uploaddir, 0777);  
}  
  //change the image name
 $uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;



  if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
 echo "<img id=\"upload_id\" src=\"".$uploadfile."\"><br />";
  } else {
   echo "error";
  }

새로운 팁은 무엇이든 환영합니다 :)

GD(또는 Imagick)를 사용하여 영상을 다시 처리하고 처리된 영상을 저장합니다.다른 모든 것들은 그저. 재미있는 해커들에게는 지루합니다.

rr가 집편: 가고r지적한대로사다니용합그리▁use를 사용합니다.move_uploaded_file()업로드할 수 있습니다.

늦은 편집:업로드 폴더를 매우 제한적으로 사용하고 싶을 것입니다.그 장소들은 많은 착취가 일어나는 어두운 구석들 중 하나입니다.모든 유형의 업로드 및 모든 프로그래밍 언어/서버에 대해 유효합니다.https://www.owasp.org/index.php/Unrestricted_File_Upload 을 확인하십시오.

이미지 파일의 보안 테스트는 4단계 보안을 생각할 수 있습니다.다음과 같습니다.

  • 레벨 1: 확장명 확인(확장명 파일 끝)
  • 2: 확인하기 2: MIME 유형 확인하기($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
  • 레벨 3: 처음 100바이트를 읽고 ASCII 0-8, 12-31(소수) 범위의 바이트가 있는지 확인합니다.
  • 레벨 4: 머리글에 마법 번호가 있는지 확인합니다(파일의 처음 10-20바이트).http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Examples 에서 일부 파일 헤더 바이트를 찾을 수 있습니다.

참고: 전체 이미지 로드 속도가 느립니다.

XSS 경고

아주 중요한 말이 하나 더 있습니다.브라우저에서 HTML로 해석될 수 있는 것을 제공/업로드하지 마십시오.

파일이 도메인에 있기 때문에 HTML 문서에 포함된 Javascript가 모든 쿠키에 액세스할 수 있으므로 XSS 공격의 일종을 사용할 수 있습니다.

공격 시나리오:

  1. 공격자는 모든 쿠키를 서버로 보내는 JS 코드가 포함된 HTML 파일을 업로드합니다.

  2. 공격자는 메일, PM 또는 단순히 자신이나 다른 사이트의 iframe을 통해 사용자에게 링크를 보냅니다.

가장 안전한 솔루션:

업로드된 콘텐츠를 하위 도메인 또는 다른 도메인에서만 사용할 수 있도록 합니다.이렇게 하면 쿠키에 액세스할 수 없습니다.이는 구글의 성능 팁 중 하나이기도 합니다.

https://developers.google.com/speed/docs/best-practices/request#ServeFromCookielessDomain

업로드 디렉토리에 새 .htaccess 파일을 만들고 다음 코드를 붙여넣습니다.

php_flag engine 0
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml

업로드한 파일의 이름을 변경해야 합니다. + 유형, 내용 등을 확인하는 것은 잊으십시오.

$_FILES['my_files']['tmp_name']에서도 "is_uploaded_file"을 실행할 수 있습니다.http://php.net/manual/en/function.is-uploaded-file.php 을 참조하십시오.

관련 질문에 올린 글을 반복하겠습니다.

Fileinfo 함수(이전 버전의 PHP에서는 mime_content_type())를 사용하여 콘텐츠 유형을 탐지할 수 있습니다.

이전 Mimtype 확장에 대한 발췌 양식 PHP 설명서, 현재 Fileinfo:

이 모듈의 함수는 파일 내의 특정 위치에서 특정 마법 바이트 시퀀스를 찾아 파일의 내용 유형과 인코딩을 추측합니다.이것이 방탄 접근법은 아니지만 사용되는 휴리스틱은 매우 잘 수행됩니다.

getimagesize()또한 좋은 작업을 수행할 수도 있지만 수행 중인 다른 검사의 대부분은 헛소리입니다.예를 들어 왜 문자열인가요?php파일 이름에 사용할 수 없습니다.PHP하는 것은 . 파일이 포함되어 입니다.php현악기, 당신은?


이미지를 다시 만드는 경우 대부분의 경우 보안을 향상시킬 수 있습니다.사용하는 라이브러리가 취약하지 않을 때까지 사용합니다.

그렇다면 안전한 이미지 재생에 가장 적합한 PHP 확장자는 무엇입니까?는 CVE 세부 정보 웹사이트를 확인했습니다.적용 가능한 트리오는 다음과 같은 확장입니다.

  1. GD(6가지 취약성)
  2. ImageMagick(44개 취약성)
  3. Gmagick(12개의 취약성)

비교해 보면 GD가 가장 적합하다고 생각합니다. 왜냐하면 GD는 보안 문제가 가장 적고 오래되었기 때문입니다.그들 중 세 명은 치명적이지만, ImagMagick과 Gmagick은 더 나은 성과를 내지 못합니다.ImageMagick은 (적어도 보안에 관해서는) 매우 버그가 많은 것 같아서 두 번째 옵션으로 Gmagick을 선택합니다.

만약 보안이 매우 중요하다면 파일 이름을 저장하고 파일 이름을 변경하기 위해 데이터베이스를 사용하고 여기서 당신은 파일 확장자를 .myfile과 같은 것으로 바꿀 수 있고 헤더가 있는 이미지를 보내기 위해 php 파일을 만들 수 있습니다. php는 더 안전하고 blow와 같은 img 태그에서 사용할 수 있습니다.

<img src="send_img.php?id=555" alt="">

또한 업로드하기 전에 EXIF로 파일 확장명을 확인합니다.

사용자가 PHP에서 파일을 안전하게 업로드할 수 있도록 하는 가장 간단한 대답은 항상 문서 루트 외부에 파일을 저장하는 것입니다.

예: 예:가 문서루다경우인 /home/example/public_html을 파저장에 /home/example/uploaded.

웹 서버에서 직접 실행할 수 있는 범위를 벗어나 안전하게 파일에 액세스할 수 있는 몇 가지 방법이 있습니다.

  1. PHP, Perl 등의 스크립트를 실행하지 않는 정적 콘텐츠를 제공하기 위해 별도의 가상 호스트를 설정합니다.
  2. 다른 서버(예: 저렴한 VPS, Amazon S3 등)에 파일을 업로드합니다.
  3. 파일을 동일한 서버에 보관하고 PHP 스크립트를 사용하여 요청을 프록시하여 파일이 실행 가능하지 않고 항상 읽을 수 있는지 확인합니다.

그러나 이 목록의 옵션 1 또는 3으로 이동하고 응용 프로그램에 로컬 파일 포함 취약성이 있는 경우에도 파일 업로드 양식은 여전히 공격 벡터가 될 수 있습니다.

사용자가 이미지를 업로드할 때 웹 사이트를 안전하게 유지하는 가장 좋은 방법은 다음 단계를 수행하는 입니다.

  • 이미지 확장 확인
  • get image size ()기능을 사용하여 이미지 크기를 확인합니다.
  • 그 후에 "file_get_get_get" 함수를 사용할 수 있습니다.
  • 결국 당신은 당신의 데이터베이스에 file_Content를 삽입해야 합니다! 당신의 의견은 어떻습니까?

어제 최고의 보안 솔루션을 찾아봤는데 GD가 그 중 하나이기 때문에 추가 앱을 사용하는 것 같습니다. 하지만 누군가 좋은 서버를 위한 돈이 부족하면 서버 응답이 크게 지연될 수 있습니다.하지만 저는 몇 가지 속임수를 생각해냈지만 갤러리나 이미지 미리 보기가 없고 업로드된 파일을 다운로드하는 옵션만 제공하는 경우 한 가지 시나리오에서만 가능합니다.따라서 첫째, 이름을 즉시 변경하고 파일의 지퍼를 내린 후 소스 파일을 삭제해야 합니다. 그러면 누구도 숨겨진 코드를 실행할 가능성이 없습니다. 따라서 이 솔루션은 서버 전용으로 안전합니다. 파일을 다운로드하는 사용자가 감염된 사용자를 열었기 때문입니다. 하지만 저의 경우는 문제가 아닙니다.

br

이미지 파일의 경우 이름을 바꾼 후 파일 사용 권한을 변경하여 실행되지 않도록 할 수도 있습니다(rw-r--r--).

저는 업로드된 각 파일에 대해 새로운 무작위 4바이트 번호를 생성한 다음, 이 4바이트로 파일의 내용을 XOR(필요한 만큼 반복)하고 마지막으로 저장하기 전에 4바이트를 파일에 첨부하는 php-upload-script를 사용하고 있습니다.

다운로드를 위해서는 4바이트를 파일에서 다시 잘라내야 하며, 내용은 다시 XOR로 처리되어 고객에게 결과가 전송됩니다.

이렇게 하면 서버에 저장한 파일이 실행 가능하지 않거나 응용프로그램에 대해 어떠한 잠재적 의미도 가질 수 없습니다.또한 파일 이름을 저장할 추가 데이터베이스가 필요하지 않습니다.

다음은 제가 사용하는 코드입니다.

업로드:

        <?php
            $outputfilename = $_POST['filename'];
            $inputfile = $_FILES["myblob"]["tmp_name"];
            $tempfilename="temp.tmp";

            if( move_uploaded_file($inputfile, $tempfilename) ) {
                $XORstring = random_bytes(4);

                $tempfile=fopen($tempfilename, "r");
                $outputfile=fopen($outputfilename, "w+");
                flock($outputfilename, LOCK_EX);

                fwrite($outputfilename, $XORbytes1);

                while ( $buffer = fread($tempfile, 4) ) {
                    $buffer = $buffer ^ $XORstring;
                    fwrite($outputfilename, $buffer);
                }

                flock($outputfilename, LOCK_UN);

                fclose($tempfile);
                fclose($outputfile);

                unlink($tempfilename);
            }

            exit(0);
        ?>

다운로드:

        <?php
            $inputfilename = $_POST['filename'];
            $tempfilename = "temp.tmp";

            $inputfile=fopen($inputfilename, "r");
            $tempfile=fopen($tempfilename, "w+");
            flock($tempfile, LOCK_EX);

            $XORstring = fread($inputfile, 4);

            while ( $buffer = fread($inputfile, 4) ) {
                $buffer = $buffer ^ $XORstring;
                fwrite($tempfile, $buffer);
            }

            flock($tempfile, LOCK_UN);

            fclose($inputfile);
            fclose($tempfile);

            readfile($tempfile);
            unlink($tempfile);

            exit(0);
        ?>

언급URL : https://stackoverflow.com/questions/4166762/php-image-upload-security-check-list

반응형