2011-09-06 4 views
12

나는 다양한 시장/국가에 대한 노출이 많은 현재의 스크립트를 대체 할 PHP 스크립트를 개발합니다. 다른 사람들 간의이 스크립트는 사진 업로드 기능을 제공합니다.PHP 이미지 업로드 보안 접근

많은 문제에 대해 읽은 후 아래에 설명 된 방법을 따랐습니다. 보안에 대한 귀하의 의견에 진심으로 감사드립니다.

  1. 사진은 웹 루트 외부의 개인 777 폴더에 업로드됩니다.
  2. 흰색 나열된 확장명에 대한 검사가 수행됩니다 (jpgs, gifs, png 만 허용). 다른 모든 항목은 삭제됩니다.
  3. 최소 최대 크기 및 사진 유효성을 확인하기 위해 getimagesize를 사용합니다.
  4. mimetype과 파일 확장명이 일치하는지 확인하십시오.
  5. 업로드 된 사진을 표준 치수에 맞게 크기 조정 (imagecopyresampled 사용).
  6. 생성 된 파일을 jpg로 저장합니다.
  7. 원본 파일 제거.
  8. 사진을 새로운 이름 (무작위가 아닌), 즉 img51244.jpg로 저장하십시오.
  9. 예측할 수없는 알고리즘에 따라 새 사진을 공용 폴더의 변수 하위 디렉터리 (권한 777 개)로 이동합니다. 즉, img10000.jpgphotos/a/f/0/img10000.jpg에 저장되고 img10001.jpgphotos/0/9/3/img10001.jpg에 저장됩니다. 이는 다른 이유 (정적 콘텐츠 제공 또는 CDN 사용을위한 하위 도메인 사용)로 수행됩니다.

스크립트는 Linux 전용 서버에서 실행됩니다.

+0

아무 것도 나에게 여기 저기 뛰어 오르지 않습니다. 777 권한이 떨어져 폴더에 - 나는 그것을 이해, 777 권한이있는 경우 개인 아닙니다. 하지만 지금까지 내가 말할 수있는 한 서버가 손상된 경우에만 문제가 될 것입니다 (적어도이 스크립트를 통해 나에게 잘 보이지 않습니다) – jammypeach

+2

777은 안전하지 않은 소리를냅니다. 가능한 관련 http://stackoverflow.com/questions/3644138/secure-user-image-upload-capabilities-in-php – ajreal

+0

매우 자유로운 권한을 제외하고 나에게 아주 좋은 소리. 아마 그들은 다소 제한 될 수 있습니까? 그렇지 않으면 EXIF ​​데이터 제거를 포함하여 내가 생각할 수있는 모든 작업을 수행합니다. –

답변

3

또한 getimagesize가 사용 가능한 RAM 메모리를 초과 할 수 있으므로 업로드 된 파일 크기를 확인해야합니다. 또한 스크립트가 언제든지 중단 될 수 있다고 가정하면 (예 : 전기가 끊어지는 경우), 불필요한 파일을 제거하기위한 정리 절차를 구현해야합니다.

+1

업로드 가능한 최대 파일 크기는 php.ini에서 이미 제한되어 있습니다. – Maerlyn

+0

예, 그렇긴하지만 RAM 제한을 초과하지 않는 것으로 충분하지는 않습니다. –

+0

php.ini의 크기를 초과하면'$ _FILES'에 파일 이름을 얻지 못하기 때문에 크기를 확인할 수 없습니다. – Maerlyn

-1

아주 완벽한 접근 방법이지만 코드 실행 방지 메커니즘이 없습니다.

이미지의 내용이 절대로 포함되거나 필요없는 호출로 포함되거나 eval()을 통해 실행되는지 확인해야합니다.

그렇지 않으면 파일 끝에 포함 된 PHP 코드가 실행될 수 있습니다.

또한 이미지 콘텐츠 (예 : file_get_contents 및 "<? php"를 검색하는 정규식)에서 PHP 코드를 검색 할 수는 있지만 의심할만한 코드를 제거하지 않고 100 % 안전한 방법을 찾을 수 없습니다 일부 (유효한) 이미지.

+0

서버가 잘못 구성되어 있지 않으면 PHP 코드가 JPG 파일에서 어떻게 실행되는지 알 수 없습니까? –

+0

아무런 의미가 없다. 분명히 아무도 이미지에 eval 또는 include를 부르지 않을 것이다. PHP를 사용하기 전에는 누군가가 생각하는 시나리오를 생각할 수 없습니다. –

+0

리샘플링 된 사진이 발생하자마자 원본 파일이 삭제됩니다. 다음의 PHP 함수에서만이 순서대로 사용됩니다 : move_uploaded_file, 파일 크기, getimagesize, imagecreatefromjpeg, imagecopyresampled. – Alex

4
  1. chmod 0777이있는 디렉토리는 정의에 따라 개인용이 아닌 서버에 로그인 한 다른 사용자에게 공개됩니다. 올바른 사용 권한은 700이며 apache (또는 귀하의 웹 서버가 실행되는 모든 사용자)이 소유합니다. 왜 웹 루트 외부에있는 경향이 있기 때문에 여기에 PHP의 기본 임시 디렉토리를 사용하지 않을지 모르겠습니다.
  2. 화이트리스트는 좋은 아이디어입니다. 올바른 구현이되도록주의하십시오. 예를 들어, 정규 표현식 /.png/은 실제로 apng.php과 일치합니다.
  3. 이 단계는 좋은 아이디어입니다. 기본적으로 파일 매직을 검사합니다.
  4. 꼭 필요한 것은 아닙니다. 앞의 두 단계에서 우리는 확장자와 파일 형식이 올바른지 확인했습니다. 클라이언트가 올바른 MIME 유형을 지정해야하는 경우 제공된 MIME 유형과 위에서 결정한 MIME 유형이 동일한 지 확인해야합니다.

5 단계부터 8 단계까지는 보안과 관련이 없습니다.

9 단계 : 사이트에서 모든 사용자가 모든 사진을 볼 수 있다고 가정합니다. 그렇지 않은 경우 상당히 긴 URL (예 : 이미지의 해시)이 포함 된 URL 체계가 있어야합니다.

+1

(-1) 777은 웹을 통한 접근성면에서 대중을 의미하지 않습니다. 그리고 귀하의 정규식 예제는 어쨌든 이것은 어떤 어리 석음이라도 함축합니다 ... 그리고 BTW exe는 windows extension입니다 ... :/ – Raffael

+0

@ Raffael1984 phihag가 알고 있다고 생각합니다. 같은 웹 서버 *에있는 다른 사용자에게 접근하기 쉽다는 점에서 여전히 공개되어 있습니다 * * 문제입니다. 그러나 3)을 올바르게 수행하면 2) 단계는 불필요하다고 동의합니다. –

+0

@ Raffael1984 True. 그 단계가 왜 필요한지 나는 확신 할 수 없다. 답변을 업데이트했습니다. – phihag