PHP 에서 파일 업로드 기능을 구현할때 가장 안전한 방법
글쓴이: 망치 / 작성시간: 토, 2006/09/09 - 12:38오전
간단하게 파일 업로드 해둘 수 있는 페이지를 만들어뒀습니다.
업로드된 파일의 mime type 을 판별해서 허용할지 안할지 판단하게 해두었는데 이렇게 해두니 같은 확장자여도 업로드 되는 파일이 있고.. 안되는 파일도 있더군요.
단순히 확장자만 판별하게 하는방법도 생각해봤는데 이럴 경우 보안 문제가 발생할 수 있다고 해서 선뜻 방식을 바꾸지 못하고 있습니다..
업로드된 파일로 인해 보안문제가 발생할 여지를 최소화 하고, php 내장 mime type 을 통하지 않고도 원하는 파일 타입을 구분해서 허용할 수 있는.. 조금은 구체적으로 실제 사용되고 있는 방법에 대해 조언을 부탁드립니다.
Forums:
1. 파일 타입은
1. 파일 타입은 확장자로 구분
2. 파일 이름을 안전한 확장자를 가진 이름으로 변환해서 저장. 1234_abc.data
3. 파일을 저장할때 퍼미션을 반드시 644, 666 등으로 저장.
4. 파일을 다운받을 때는 URL로 직접 접근하게 하지 말고 php의 fpassthru함수를 통해 전송.
5. URL로 직접 접근할 수 없는 곳에 파일 저장. 웹 디렉토리가 home/user/public_html이면 home/user/data 쪽에 저장.
6. 성능의 손해를 감수할 수 있다면, 파일 내용을 검사해서 필터링한다. #!/bin/sh 나 #!/bin/bash 같은거.
아무 검사 하지 않습니다.
아무 검사 하지 않습니다.
다운로드된 파일의 파일명은 테이블에 보관하고,
실제 파일은 시퀀스나 MD5 HASH 를 파일명으로 저장합니다.
파일은 public_html 밖에 (../files/) 빼 두고,
(파일 관리를 위해 1000 개마다 디렉토리를 바꿔주는 등의 로직이 있으면 더욱 좋습니다.)
다운로드는 http://www.site.com/files.php/(md5hash or sequence)/원래파일명.jpg
이런식의 링크로 해결합니다. (혹은 헤더에 파일명을 명시할 수도 있겠지요.)
files.php 에는 이어받기가 되도록 헤더처리를 해 주면 더욱 효과적입니다.
md5hash 를 선택하실 때는 파일의 용량도 함께 표기가 되는것이 좋습니다.
만에 하나 있을지 모를 같은해쉬를 가지는 다른 파일의 위협을 줄이기 위해...
emerge money
https://xenosi.de/
이 경우의 단점은 1.
이 경우의 단점은
1. ftp등과 같이 쓸 수 없다.
2. ftp를 쓸 수 없기 때문에 한꺼번에 많은 파일을 올릴 수 없다. (이미지 파일이 1000여개라고 할 때)
php 의 업로드 기능을
php 의 업로드 기능을 이용하는것에 대한 글입니다.
ftp 를 이용하는것은 어차피 php 에서 제어가 안되는데요.;p
꼭 해야 한다면 tarball 해서 올리고, php 스크립트 짜서 돌리지요.
제가 위에 적은 기능이 구현되었다면,
짤 코드는 몇줄 안되죠. :)
emerge money
https://xenosi.de/
php 로 넘어오는 $_FILES
php 로 넘어오는 $_FILES 의 mime type 은 신뢰하지 마세요.
순전히 브라우저가 보내는 정보를 믿어주는거라,
신뢰도 0 입니다.
실제로 몇년전의 모질라 같은 경우 그냥 확장자로 mime type 을 선택해서 보내더군요.
mime type 을 구분해야 할 일이 있다면,
php 의 mime_content_type() 이나 pear 의 MIME_Type 같은것을 이용하세요.
emerge money
https://xenosi.de/
아, 현재 상태가
아, 현재 상태가 mime_content_type() 를 이용하는 중이었습니다.
조언주신대로 구현할 방법을 고민해보겠습니다.
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
php 내부에서 아래와
php 내부에서 아래와 같은 파일뒤 파라미터는 Request_URI 같은걸 이용해서 파싱하는건가요?
http://www.site.com/files.php/(md5hash or sequence)/원래파일명.jpg
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
/phpinfo.php /phpinfo.php/asd
/phpinfo.php
/phpinfo.php/asdf/zxcv
지금 해 보니 좋은게 보이네요.
PATH_INFO
얼른 고쳐야겠습니다.
emerge money
https://xenosi.de/
PATH_INFO 좋네요. ㅎㅎ
PATH_INFO 좋네요. ㅎㅎ
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
저게 되요???
x.php/aaa/bbb/ccc
이거... PHP에서 처리가 가능하단 말이죠??? PHP는 아니어도 저런 비슷한 것을 많이 본 거 같은데 가능하단 소리군요... 음... 좀 더 저걸 활용하는 자세한 예가 잇으면 보여 주실 수 있을런지.. 뭔가 해서 봤더니 재미 있는 것이 있네요...
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!
사람천사
모니위키에서 PATH_INFO
모니위키에서 PATH_INFO 사용합니다. PATH_INFO를 직접 파싱하는데, 이 경우 AcceptPathInfo On으로 설정되어 있어야 합니다. 이 경우 mod_rewrite를 쓸 필요 없다는 장점이 있는데, 반대로 mod_rewrite를 함께 쓰려고 하는 경우 (예를 들어 스크립트 이름을 감추려고 한다거나) PATH_INFO를 제대로 파싱하는데 특별 처리를 하거나 해야하죠.
ex>
ex> http://research.com/test.php/imagefile1.jpg
메뉴얼을 참고해서 간단하게나마 파일을 땡겨오는 함수를 만들어봤습니다.
IE 에선 이미지 접근시 바로 표시가 되는데, FF 에선 다운로드창이 떠버리네요.. 컨텐츠 타입 문제인것같기도하고..
이건 어떻게 해결해야하나요?;;
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
이미지가
이미지가 웹브라우저에서 보여지길 원하시면
application/octet-stream
를image/jpeg
로 하시면 될듯.파일 컨텐츠가 항상
파일 컨텐츠가 항상 이미지만 있진 않을것같거든요..
동영상도 있을테고.. 문서도 있을테고.. 압축파일 등등..
그렇다고 mime_content_type 을 쓰면 지금과 마찬가지로 제대로 판별 안되는 파일이 종종 있을거구요..
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
이미 보안이 강화
이미 보안이 강화 되었으므로,
$_FILES 의 mime type 을 테이블에 함께 저장하고,
다운로드시 그것을 헤더에 뿌리세요.
emerge money
https://xenosi.de/
아.. 그게 좋겠네요.
아.. 그게 좋겠네요. ㅎ
감사~!
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
이걸...
아래와 같은 부분을 어떻게 잘 활용 해 보심이...
RG-Board에서 사용된 헤더입니다. (전 웹프로그래밍이 주업이 아니기 때문에 전부 저 헤더의 뜻을 이해 하진 못 했습니다.)
그리고 파싱을 직접 하면 되겠군요. x.php/xxx.html 이런건 이해 했습니다.
그리고 저기에 파일명을 MD5로 암호화 해서 저장하고 받을 때 그 MD5 문자열을 대입 하게 하면 보안이 강화 되겠군요.(어떤 분이 말씀 해 주신 내용인 듯...)
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!
사람천사
캑!
DB에 자료를 넣고 그걸 그냥 뿌린다는 말씀이신가요??? 무서운 방법이군요. 바이너리로 집어 놓고 다시 빼와서 뿌리면 되겠군요.(뭐 저도 저런걸 언젠가는 구현 해야 할 날이 올 거기 때문에...)
뭐, 스트림으로 보내는 것 만 해도 상당히 보안에 신경을 쓴 것이 되 버리겠군요. 거기다가 일반적인 방법으론 접근조차 할 수가 없으니 더 보안성이 높아 지고, 뭐 좋은 방법이네요.(근대 아무레도 DB에 파일 내용을 직접 저장 한다고 생각 한 것은 잘못 이해 한 듯...)
아무튼 좋은거 잘 만드세요 ㅎㅎㅎ.
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!
사람천사
업로드된파일은 DB 가
업로드된파일은 DB 가 아니라 아파치가 접근할 수 없는 디렉토리에 저장됩니다. PHP 가 내부적으로 접근해서 파일을 읽어다가 뿌려주는식이구요.
그나저나 이걸 만들어서 서비스할 녀석이 문제가 생겨서 걱정이 큽니다.. 아무래도 하드웨어문제같은데.. 곤란하게됐네요 ㅡ.,ㅡ;
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
그 서비스 할 서버...
제가 좀 전에 답글 단 서버 같군요 ㅋㅋㅋ... 서버 죽은게.. 저도 한 두 번이 아니기 때문에 흑흑흑... 어느정도 이해가 갑니다. message 어쩌고 체크 해 볼 시간적 여유도 없었습니다 윽.
----
일어나라! 싸워라! 그리고 이겨라!
다만!!! 의미 있는 것에 그 힘을!!!
그 능력과 노력을!!!
사람천사
컴퓨터 부품은...
다나와.. 그리고 Gmarket를 잘 이용 하면 싸게 살 수 있습니다. 욕션 같은건 안 해 봐서 모르겠고, 제가 지금까지 물건을 사면서 용산을 직접 탐방한 경우를 제외하곤 거의 다가 다나와를 통해서 산 것들입니다. Gmarket은 써 보진 않았는데 물건 가격만 한번 구경 해 본 적이 있습니다. 가격 면에선 괸찮은 것이 많더군요.
그리고 P3용 보드가 꼭 필요 하시다 싶으시면... 매일 주소로 매일을 주세요 ㅋㅋㅋ. 근대 이게 좀 불안하네요... 정말 P3가 들어 가는진. 라이저 카드 같은걸 써야만 들어 가는 거라면 불안하지 않을 수가 없겠쬬 흠.(지금 이게 슬롯에 꽂는 겁니다.)
----
Lee Yeosong(이여송 사도요한)
E-Mail: yeosong@gmail.com
MSN: ysnglee2000@hotmail.com
----
웃음... 행복... 평화... (진정한...) 희망... 사랑... 이 세상 모든것이 그렇다면 얼마나 좋을까...(꿈 속의 바램일 뿐인가...)
사람천사
말씀은 감사 ^^; 그냥
말씀은 감사 ^^;
그냥 제 컴터 본체 새로 마련하면서 쓰던걸 갖다둘까도 생각중입니다. 안정적으로 사용하던 녀석이니 이녀석은 문제 없을듯하네요. ㅎ
요즘 추세대로 듀얼코어에 맞춰서 나름대로 저렴하게 견적 내봐도 가격이 꽤 나가네요..
Intel DG965RY 132,000
G.SKILL DDR2 PC2-6400(512M x 2EA) 145,000
Intel E6300 173,000
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
그냥 메모리 1GB에
그냥 메모리 1GB에 보드/cpu 모두 9만원 안쪽으로 하시면 부담이 훨씬 덜하지요~ (단지 웹서버로 쓰실 생각이라면 CPU속도보다는 좋은 HDD와 메모리에 투자하시는게 더 낫다에 한표)
온갖 참된 삶은 만남이다 --Martin Buber
아.. 새로 구매하는건
아.. 새로 구매하는건 제가 메인으로 쓸 녀석입니다. 서버로 돌릴건 기존에 제가 쓰던 (P4-2.0) 이구요. ㅎ
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
하하하!
솔직히... 엄청난 양의 데이터 처리가 필요한 프로세스를 돌리실 것이 아니라면 듀얼코어도 필요 없지 않을 까요. 서버가 2.4G 셀D로 잘 돌아 가고 있습니다.(저의 경우)
그리고 데스크탑에 2000과 젠투를 깔아서 쓰는데.. (젠투는 얼마 전에 시작 했죠.) 이게 P4도 아닌데.. 그렇게 딸린다는 생각은.. 안 해 봤습니다. (스크린 리더만 안 띄우면...) (젠투 컴파일 엄청 느린것도 일단은 넘어감...)
뭐.. 저는 항상 돈이 쪼달리므로 저가형 장비들만 씁니다... 셀러론, (메모리는 어쩔 수 없죠. 그래도 비싸더군요.) ASRock 보드나 VIA 칩 같은걸 사용한 저가형 보드...(아니면 BX에도 조립 합니다. 그것도 아니면 I815같은게 들어간...) Ethernet은 누구나 잘 쓰는..(아닌가?) RTL-8139호환 기종... 하드는 어디서 남아 도는거 거저 얻어다 쓰거나..(사야 한다면?) 사야 되면 그냥 간단하게 삽니다. 쓸만 하다면 5년? 6년도 업그레이드를 안 하고 쓰죠.(근대 지금까지 자꾸 문제가 생겨서 바꾸는 김에 업그레이드도 계속 해 왔습니다.)
아무튼 만드시는 프로그램이 잘 돌아 가길 바라겠습니다 ㅎㅎㅎ.
----
Lee Yeosong(이여송 사도요한)
E-Mail: yeosong@gmail.com
MSN: ysnglee2000@hotmail.com
----
웃음... 행복... 평화... (진정한...) 희망... 사랑... 이 세상 모든것이 그렇다면 얼마나 좋을까...(꿈 속의 바램일 뿐인가...)
사람천사
제가 쓰던걸(P4-2.0)
제가 쓰던걸(P4-2.0) 갖다놓고 제 메인컴 본체를 새로 마련하는걸 고민중입니다 ^^ 가격 알아본것 역시 그런 이유에서 알아본것이구요
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
하는 김에...
쓰시는 컴퓨터를 업그레이드 하시려는 생각이신가 보군요.(그리고 제가 데스크탑 이야기를 한 것도.. 데스크탑이 너무 좋을 필요가 없다는 뭐 그런 소리를 하고 싶었습니다. ㅋㅋㅋ.) 뭐 아무튼... 전 될 때 까지 P3 550으로 버텨 볼랍니다... 자료는 간간히 백업을 해 줘야 겠군요 음. 그럼 잘 되시기를... 아 참. 듀얼코어나 775소켓 쓰는 것들은 열 많이 받아서 골아픕니다 윽...
----
Lee Yeosong(이여송 사도요한)
E-Mail: yeosong@gmail.com
MSN: ysnglee2000@hotmail.com
----
웃음... 행복... 평화... (진정한...) 희망... 사랑... 이 세상 모든것이 그렇다면 얼마나 좋을까...(꿈 속의 바램일 뿐인가...)
사람천사
이렇게 구현하고
이렇게 구현하고 다음과 같이 이미지를 표현했을때 IE 에서 다른이름 저장시에 BMP 로 저장되는 문제가 발생합니다. 익스에서 보안문제로 일부러 그렇게 막아둔것인지.. 아니면 다른 방법이 있을까요? 파폭에선 문제없이 저장되더군요.
수정했습니다.;;
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
'다음과 같이' 가
'다음과 같이' 가 안보이는데요,
어쨌든, 익스플로러에서 이미지의 '헤더' 나 '주소' 에 그림이 아닌듯한 느낌(?)이 들도록 표현됐는지 확인해보세요.-_-;
파일명 헤더가 포함되었는데 확장자가 없다던가,
파일타입 헤더가 엉뚱 혹은 없다던가,
url 의 파일명에 그림다운 확장자가 붙지 않았다던가... 등등...
img 태그에 적은 것이기 때문에 좀 틀려도 그림인줄 알고 보여주기는 합니다만,
저장시에 좀 이상한짓을 하는 경우를 겪어본 적이 있습니다.
emerge money
https://xenosi.de/
헤더는
헤더는 조언해주셨던대로 처음 업로드시 넘어오는 mime type 을 그대로 넘겨주었기 때문에 문제 없을테고..
희한한건 Firefox 에선 잘 되는데, IE 에서만 문제가 생깁니다. img 태그로 이미지 표시는 잘 되는데 다른이름 저장시엔 원본파일 종류와 관계없이 무조건 BMP 로 저장되더군요.
---------------------------------------
http://www.waitfor.com/
http://www.textmud.com/
다음 기사를
다음 기사를 참고하시기 바랍니다.
http://support.microsoft.com/default.aspx?scid=kb;ko;810978
http://qaos.com/article.php?sid=1363
제 기억으로는 인터넷 임시 폴더의 크기를 너무키워놔도 발생했었던 것 같습니다. 20-100MB 정도면 될 것 같습니다.
댓글 달기