2012-09-07 3 views
7

저는 a script과 스택의 도움과 친구의 도움을 받아 PHP를 거의 모르는 사람들이 사진을 업로드 할 수있는 지역 비영리 출판물의 간단한 페이지를 만들었습니다.PHP 이미지 업로드 스크립트를 악용으로부터 보호하려면 어떻게해야합니까?

나는 (무지가 아니라 고의적 인 과실의 기준에서) 보안에 큰 아니에요하지만 난이 페이지 보호하기 위해 다음과 같은 조치를 취했습니다에만 .JPG를 동의로 설정되어있는 PHP 스크립트 •

을 , .png 및 .tif 파일 업로드;
• 양식 내용을 저장하는 하위 폴더에는 권한이 700으로 설정되고 하위 폴더에는 업로드 된 사진이 저장되는 권한이 700으로 설정됩니다. 내가 관련의 htaccess로 파일을 넣어 (주를하고 내용을 저장) 한 •

<FilesMatch \.php$> 
    SetHandler php52-fcgi 
</FilesMatch> 

:
은 • 설명서에 따라, 나의 호스트는 .PHP 파일 .php로 실행되도록하여 다음과 같은 구성을 가지고 폴더 :

RemoveHandler .php 
RemoveHandler .inc 
RemoveHandler .pl 
RemoveHandler .cgi 
RemoveHandler .py 
RemoveHandler .fcgi 

는 하룻밤, 그러나 누군가는이 테스트 페이지를 발견하고 완벽하게 양성 테스트 메시지 작은 .JPG 것 같다 무엇을 제출했다. 이것은 비공식 URL이 포함 된 개인 테스트 페이지로, 나와 약 세 명의 사람들 만 알 수 있습니다. 다른 누구도이 시험을 보냈습니다.

이것은 분명히 어떤 일이 일어나는 것이 걱정되며, 나는이 페이지가 안전한지 보안에 대해 충분히 알지 못한다고 걱정합니다.

실종 신고 된 것이 있습니까?

+0

사용자가 지정한 파일 이름 ('$ _FILES [ 'upload'] [ 'name']')은 신뢰할 수 없으며 쉽게 변경할 수 있습니다. 이 확장 프로그램을 확인하지 마십시오. 'getimagesize()'가 유효한 결과를 반환하는지 확인하려면 mime 형식을 확인하십시오. 가능한 경우 자신의 파일 이름을 생성하십시오. – MarcDefiant

답변

8

업로드를 처리 할 때 $ _FILES 배열에서 찾을 수있는 모든 데이터를 위장 할 수 있다는 점에 유의해야합니다. 그것은 HTTP를 통해 여행하므로 예를 들어 실행 파일에 이미지/jpg mime을 제공하는 것이 매우 쉽습니다.

1 체크 진정한 마임은

PHP 파일의 실제 마임을 확인하려면 몇 가지 기능이 제공됩니다. 이를 위해 당신은 이미지의 속성 fileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
$filename = "/var/tmp/afile.jpg"; 
echo $finfo->file($filename); 

2 확인을 사용해야합니다

당신은 분명히에만 이미지를 업로드 할, 그래서 수신 된 파일은 폭과 높이가 있어야합니다

사용 getImageSize()을 클릭하면 이미지에 대한 모든 필수 정보가 표시됩니다. false를 반환하면 파일이 이미지가 아니므로 삭제할 수 있습니다. getImageSize도 MIME 유형을 제공 할 수 있지만 신뢰할 수 있는지 여부는 알 수 없습니다.

2.5 다시 처리 이미지 GD로 이미지를 재 처리, user628405에 의해 제안

아마 할 수있는보다 안전한 것입니다.

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png'); 

분명히 이미지 유형에 따라 조정되어야합니다. PHP 문서에서 imagecreatefrom *을 모두 참조하십시오. 이미 한 일의 또한

3 업로드 폴더 :

이 확인 확실 업로드 폴더는 웹에서 사용할 수 없습니다. 업로드 된 파일의 유효성을 검사 한 다음 필요할 경우 다른 폴더로 옮기고 파일 이름을 바꿉니다. 해커가 악의적 인 파일을 실행하는 것을 방지합니다 (URL로 접근 할 수없는 경우 해커를 실행할 수 없음).

추가 읽기 : https://www.owasp.org/index.php/Unrestricted_File_Upload

+2

일단 어떤 사람이 웹 서버 PNG 파일에''를 업로드하여 바이너리 데이터에 넣었을 때 상황이 발생했습니다. 이 코드는 실행 가능하지 않지만'include()'함수를 통해 여전히 액세스 할 수 있습니다. 그리고 불행히도'getimagesize()'는 false가 아닌 값을 반환했습니다. 나는 모든 업로드 된 이미지를'$ img = imagecreatefrompng ('vulnerable.png')에 의해 다시 저장함으로써 이러한 상황을 관리했다. – CodingHamster

+0

나는이 모든 것에 대해 상당히 새롭고 숙제를 두려워하지 않지만 몇 가지 질문이있다. 첫째, fileinfo 및 getImageSize 명령을 추가 할 것인가? , 그리고 파일 이름 바꾸기 비트는 물론 스크립트의 "case 파일"부분 안에 있습니까? – JeanSibelius

+0

모든 검사는'$ _FILES [ 'my_files'] [ 'tmp_name']'변수에서 가능한 한 빨리 완료되어야합니다; everithing이 잘된다면, 파일을 옮기고, 이름을 바꾸고, 당신이해야 할 일을 다 할 수 있습니다. – grunk

0

파일의 MIME 유형을 확인할 수 있지만 PHP 처리기가 .php 파일 만 실행할 수 있고 스크립트에 업로드 된 .php 파일을 저장하지 않는 경우 걱정하지 않아도됩니다. 어떤 보안 누출도 노출되지 않습니다.

이것은 서버에 설치된 다른 서버 측 스크립팅 언어뿐만 아니라 .php 파일에도 유효합니다.

더 나은 아이디어는 파일 시스템에 저장하기 위해 허용하는 확장명을 흰색으로 유지하는 것입니다.

+1

이것은 업로드와 직접적인 관련이 없지만 일부 malicous php 코드가 포함 된 이미지를 주석으로 업로드 할 수 있습니다. 사이트에 LFI 취약점이있는 경우 이미지를 포함시키고 악성 코드를 실행할 수 있습니다. – MarcDefiant

0

들어오는 파일의 MIME 형식과 파일 확장명을 무시합니다. 이들은 가짜 일 수 있습니다.

해당 애비뉴가 내려 가면 해당 파일을 디렉토리에 저장하십시오.

해당 디렉토리가 이미지 (음악) 만위한 것인지 확인한 다음 파일 형식을보고 스크립트가 올바른 확장자를 배치하도록하십시오.

해당 디렉토리에서 PHP 또는 다른 것을 실행할 수 없도록해야합니다.

이렇게하면 안전하게 유지됩니다.

4

콘텐츠 형식을 포함하여 클라이언트에서 데이터에 의존하지 마십시오!

업로드 된 파일을 웹 루트에 저장하지 마십시오. 업로드 된 파일은 더 나은 제어를 위해 스크립트를 통해서만 액세스 할 수 있어야합니다.

업로드 한 파일을 원래 파일 이름과 확장명으로 저장하지 마십시오! 나중에 검색 할 수 있도록이 데이터를 데이터베이스에 저장하십시오.

관련 문제