2009-03-10 9 views
8

사용자가 파일을 업로드 할 때 무작위로 다른 사용자의 업로드 파일로 바뀌면 마침내 문제가 PHP로 추적되고 tmp 파일 이름이 다시 사용됩니다. 이 문제를 해결할 수있는 방법이 있습니까? 더 나은 임의의 이름을 만드는 방법이 있습니까? 그것은 임의의 파일 이름 시드가 약 해지면 시간이 지남에 따라 저하되는 것 같습니다. http://pastebin.com/m65790440업로드 용 PHP 임시 파일 이름이 충돌합니다.

어떤 도움이 크게 감사합니다 :이 여기에 같은 tmp 파일 이름이 사용됩니다 다른 업로드하여 덮어 쓰기 방법을 보여주는 로그는 PHP 5.2.8 및

FreeBSD의 7.0에 있습니다. 나는 이것을 4 개월 넘게 고치려고 노력해 왔으며 시간이 지남에 따라 더 악화되었다. 고맙습니다.

편집 : 이것은 PHP 코드의 문제가 아님을 명심이가 어떤 PHP 코드에 도달하기 전에 일어나고, 파일이 $ _FILES를 통해 수신 [ '이름'] [ 'tmp_name이']이 잘못이 수신 될 때 업로드 처리 스크립트에 도달하기 전에 다른 사람이 업로드 한 파일을 덮어 쓴다는 것을 추적했습니다.

+0

그것은 당신의 tmp 디렉토리가 당신이 파일을 복사/이동하는 문제 또는 dir에 관한 것입니까? – Greg

+0

FreeBSD 8 및 PHP 5.3에서 같은 문제가 발생합니다. 아주 간단한 업로드 스크립트가 있습니다. 5 번의 테스트에서 충돌 가능성이 높습니다. 이것은 정말로 나쁘다. 나는 아직 아이디어가 없다. 위에서 언급 한 것처럼이 문제는 Google에도 어렵습니다. –

답변

-1

너무 많은 파일 이름으로 GUID 생성기를 사용하는 것이 좋습니다.

+0

PHP 파일 업로드 방식을 무시하는 방법이 있습니까? 현재 php는 'phpxxxxx'스키마를 사용합니다. – mrmanman

2

PHP가 아파치에서 실행되고 있습니까 (mod_php)?

는 그런 다음, 그 이름이 당신의 PHP getmypid()을 포함 create a per-process temporary upload directory에 시도 할 수 ini_set 당신의 PHP 프로세스 'upload_tmp_dir 디렉토리 합니다. 모든 php 프로세스가 모든 요청에 ​​대해 생성되는 경우 이는 작동하지 않습니다.

+0

PHP 파일 업로드 방식을 무시하는 방법이 있습니까? – mrmanman

+0

아니요,하지만 임시 파일이 덤프 된 임시 디렉토리를 무시할 수 있습니다 (런타임시). – vladr

0

업로드 한 파일을 사용자 디렉토리로 이동하십시오. 임시 파일은 제거해야합니다.

+0

올바른 픽스입니다. PHP의 임시 업로드 파일은 처리 스크립트가 실제로 속한 위치로 이동하는 데 걸리는 시간 동안 머물러야 만합니다. – chaos

+0

어느 시점에서 PHP의 정책은 이동/이름을 변경하지 않은 경우 요청이 끝난 후 임시 파일을 삭제하게되어 해당 버전을 지나서 업그레이드하면 전체 현재 메커니즘도 손상됩니다. – chaos

+0

이동 중입니다. PHP 업로드 처리 스크립트가 $ _FILES [ 'name'] [ 'tmp_name']에서받는 파일이 – mrmanman

4

PHP 설치 또는 임의의 파일 이름을 생성하기 위해 PHP가 내부적으로 사용하는 시스템 호출 (매우 일반적으로 tempnam)에 심각한 문제가있는 것 같습니다.

다른 사람 : PHP는 사용자 코드가 처리되기 전에 업로드 된 파일을 내부적으로 처리합니다. 이러한 이름은 $_FILES['file']['tmp_name'] (여기서 'file'은 양식의 파일 입력 요소의 (인용 된) 이름입니다)에 저장됩니다.

+0

으로 시작하는 것은 잘못되었습니다. 예, 당신이 맞다고 생각합니다. 이제 어떻게 고칠지를 알아야합니다. = B – mrmanman

+0

저는 ' 내가 Google에서 무엇인가를 찾을 수 있었는지 알았지 만 나는 그렇지 않다. upload_tmp_dir을 다른 디렉토리로 설정하면 여전히 문제가 발생합니까? – Powerlord

+0

그래, 그냥 그것을 밖으로 테스트하고 upload_tmp_dir 뭔가 다른 설정되어있을 때 문제가 여전히 발생합니다, "noatime"(파일을 업로드 할 수있는)/var 파티션에 설정이 영향을 미칩니 까? – mrmanman

3

FreeBSD 7의 libc 구현에서 관련 코드를 _gettemp으로 쫓아 낸 후 파일 tmp_name의 내용이 어떻게 잘못되었을 수 있는지 명확하지 않습니다. (를 추적하려면, 당신은 PHP 5.2.8의 사본을 다운로드하고 main/rfc1867.c 읽을 수있는 - 라인 main/php_open_temporary_file.c에서 1018 호출 함수는 함수의 주요 작품은, 그러나 라인 (97)에 시작입니다 않는 라인 227에 시작, 기본적으로 임의의 파일 이름을 실제로 생성하기 위해 _gettemp (위와 동일)을 사용하는 66 (링크 된) 라인의 FreeBSD libc implementation에있는 시스템의 mkstemp에 대한 래퍼입니다. 그러나 the manpage for mkstemp은 BUGS 섹션에서 arc4random() function이 .하지 재진입이 2 개 동시 요청이 중요한 코드 섹션을 입력하고 반환 될 가능성이 될 수있는 동일 tmp_name - 나는 (아파치가 논평하는 방법 mod_php 또는 PHP를 CGI 중 하나와 함께 작동하는 방법에 대해 너무 작은 알고 FastCGI를/PHP를 사용하지만) 나는이 시간에이 성공적으로 언급 할 수 - -cgi가 작동 할 수 있습니다.

그러나, 고유성의 유일한 소스로 tmp_name의 파일 이름 부분을 사용하는 경우, 매우 파일 tmp_name 자체가 무효 인을 겪고 있지만, (예를 들어, 다른 업로드 된 파일 대신 충돌하지 않는 경우 simpliest 솔루션을 목표로 저장된 파일 이름), birthday paradox으로 인해 충돌이 발생할 수 있습니다. another question에는 이동할 5,000,000 개의 파일이 있고, still another question에는 하루에 30-40k 업로드를 받는다고 언급되어 있습니다. 이것은 생일의 역설적 인 충돌을위한 주요 상황으로 나를 때린다. mktemp man page은 (PHP처럼 여섯 개의 'X'를 사용하는 경우) 56,800,235,584 개의 가능한 파일 이름 (62 ** 6, 또는 62 ** n, 여기서 n은 'Xs'의 수 등)이 있음을 언급합니다. 그러나 500 만 개가 넘는 파일이 있다면 충돌 가능성은 approximately 100%입니다. ((파일 * (files-1)/2)가 이미 220 충돌의 순서를 이미 경험했을 것입니다.)/(62 ** 6)은 파일이 5,000,000 인 모든 것을 의미합니다. 이 문제가 발생한 경우 ( 생성 된 업로드 된 파일 이름에 추가 엔트로피를 추가하지 않는 경우) move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.'))과 같은 형식을 시도해 볼 수 있습니다. 임의의 파일 이름에 임의성을 추가하여 충돌을 방지 할 수 있습니다. 또 다른 방법은 두 번째 'X'를 134 행의 main/php_open_temporary_file.c에 추가하고 다시 컴파일하는 것입니다.