사이트 내 전체검색
PHP
안전한 PHP 파일 업로드 구현 체크 리스트
로빈아빠
https://cmd.kr/php/354 URL이 복사되었습니다.

본문

원문 : http://hungred.com/2009/08/17/useful-information/secure-file-upload-check-list-php/


 

1. Content Type 검증

 

$_FILES['uploadfile']['type']로 MIME type 검증

 

* PHP가 받아오는 MIME type은 웹브라우저가 넘겨주는 값을 그대로 쓴다. 대다수 웹브라우저들은 확장자로 MIME type을 결정하기 때문에 신뢰도가 떨어지는 건 어쩔 수 없다.

 

 

2. Image 파일 검증

 

$imageInfo = getimagesize($_FILES['uploadfile']['tmp_name']);

 

getimagesize로 MIME type 검증하기

 

* 이미지 업로드시 쓰는 방법이다. 이미지라면 제대로 값을 return 해주지만 그렇지 않으면 return을 못한다.

 

 

3. 확장자 검증

 

$filename = $strtolower($_FILES['uploadfile']['name']);

 

$fileInfo = pathinfo($filename);

 

echo $fileInfo['extension'];

 

* '.'단위로 explode해서 end로 확장자를 구하는 게 원문이지만, pathinfo 함수로도 확장자를 구할 수 있다. 여튼 이것도 확장자로만 검사하기 때문에 당연히 정확한 건 아니다. 가장 좋은 거야 당연히 파일 내용 자체를 검사하는 거지만, 성능 손해가 만만치 않기에 -0-...

 

 

4. 업로드 디렉토리

 

검증이라고는 생각이 안 되지만, 어느 정도의 방어 수단인 것 같다.

 

내 경우에는 이미지만 받는 게 보통이라서 업로드 디렉토리와 다운로드 디렉토리가 같다. (-_-;;)

 

물론 그렇지 않은 경우에는 업로드 디렉토리는 외부에서 접근 불가능하고 다운로드 프로그램으로만

 

다운로드 하도록 한다.

 

또한 업로드 파일이 너무 많아지면 훗날 한 디렉토리에 파일이 많아지므로 년 + 월로 매번 디렉토리를 생성해서

 

업로드를 한다.

 

예) 2009년 8월이면 /upload/200908

 

 

5. Include Function

 

원문에 있길래 적어놓기는 하는데... 사용자 입력 값만을 믿고 import하는 건 잘못된 거다.

 

왜 이런 예가 있는지 이해가 안 된다.

 

정 사용자 입력 값으로 import를 해야한다면,

 

switch ($_GET['import']) {

    case 'foo':

        include $_GET['import'].'.php';

        break;

 

    case 'abc':

        include $_GET['import'].'.php';

        break;

 

    default:

        include 'qwe.php';

        break;

}

 

이런 식으로 정확한 값만 통과할 수 있도록 해야 된다고 생각한다.

 

원문의 예제는 단지 isset만으로 값이 넘어왔나 안 넘어왔나만 확인 하는데... 만약 빈 값으로 넘기면 어쩌려고?

 

GET, POST, COOKIE는 사용자 입력 값이다. 언제든 위변조가 가능하다. SESSION도 따지고 보면 사용자 입력

 

값에 의해 가공되므로 SESSION도 100% 믿으면 안 된다.

 

 

6. 임의 파일명

 

난 사용자가 올린 파일명을 그대로 안 쓴다.

 

한글 파일명은 UTF-8 다시 보내기 문제도 있고, 이래저래 사용자 입력 값보다 더 무서운 게 사용자가 올리는

 

파일이기 때문이다. 내 경우에는

 

랜덤값 여섯자리 + 타임스탬프

 

로 파일명을 정한다.

 


 

* 되도록이면 어느 정도 구현된 파일 업로드 함수를 쓰는 게 낫다고 생각한다. 물론 경우마다 다르겠지만 PHP 자체만으로 업로드를 하는 경우는 거기서 거기인 경우가 많다. 가장 좋은 건 사용자 입력 값은 최소로 하는 게 좋다는 거다. 일반적인 커뮤니티 게시판에서는 이미지만 업로드 되면 된다. 소수의 사용자를 위한 배려가 큰 악재로 바뀌는 것보다는 낫다고 생각한다.

댓글목록

등록된 댓글이 없습니다.

PHP
871 (12/18P)

Search

Copyright © Cmd 명령어 3.145.72.44