Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [php] czy ten skrypt uploadu jest bezpieczny?
AndyPSV
post 31.10.2011, 17:03:27
Post #1





Grupa: Zarejestrowani
Postów: 393
Pomógł: 5
Dołączył: 6.02.2003
Skąd: The.Luciferian.Doctrine.p
df

Ostrzeżenie: (30%)
XX---


tzn. czy nie pozwoli np. na wrzucenie plikow .php albo cokolwiek innego (o czym moge nie wiedziec)

prosilbym o analize, dziekuje

  1. <?php
  2.  
  3. /* SECURITY HOLE: USER CAN UPLOAD FILES TO OTHER USER IF HE WANTS TO HACK SOMETHING; practically: low priority, nobody would engage in such action; BUT IT NEEDS TO BE FIXED */
  4. /* DON'T UPLOADS PARTICULAR IMAGES WITH "NAMES" DIFFERENT */
  5.  
  6. include($_SERVER['DOCUMENT_ROOT'].'/libs/db/index.php'); include($_SERVER['DOCUMENT_ROOT'].'/libs/db/db.php'); if(!ctype_digit($_GET['id'])) die('!ctype_digit'); include($_SERVER['DOCUMENT_ROOT'].'/libs/url/index.php'); define('N','/');
  7. $q = q('SELECT t,t2 FROM `'.PRFX.'cfg_en` WHERE id = 1'); if(n_r($q) == 0) die('no cfg'); $cfg = f($q);
  8. $q = q('SELECT * FROM `'.PRFX.'ads` WHERE id = "'.$_GET['id'].'" LIMIT 1'); if(n_r($q) == 0) die(H.'no ad'); $r = f($q); /*include($_SERVER['DOCUMENT_ROOT'].'/libs/auth/index.php'); $u = isUlogd($cfg['t2']); if($u['id'] <> $r['u']) die(H.'u <> usr [you\'re trying to edit somebody\'s ad; no permission]');*/ $r['t_'] = _url($r['t']);
  9.  
  10.  
  11. if(!empty($_FILES)) {
  12. /****
  13. * GALERIE TWORZY mozliwa jest ona do edycji
  14. * musi poczekac [3] KOMPRESUJE PLIK, AUTOMATYCZNIE I TWORZY MINIATURE (TZW FACEBOOK SIZE)
  15. * 90%; stala wielkosc watermarka (ale to punkt [3] musi byc zrobiony)||||||dodaje watermark na srodku obrazka albo gdzies po boku z ID obrazka (id ogloszenia)
  16. * 90% done, but it needs to change the thumbnail (image resized) value [2] sprawdza czy nie wystepuje juz plik o tej samej tzw. checksum; jesli wystepuje to go nie uploaduje
  17. * 90% [zrobione] [1] tworzy folder osobny (do jednego folderu z ID wrzuca) dla kazdego dodanego zdjecia; na kazde 5 000 subfolderow jest jeden znowu podkatalog ||||| w nieskonczona petle wrzucic
  18. * przy kasowaniu zdjec automatyczne usuwanie ich z bazy i z serwera; jak skasuje wszystkie to tez automatycznie usuwa folder
  19. * [czeka na punkt [3]]mozliwosc tworzenia miniatury ze zdjecia (czyli inne)
  20. * SIZE_LIMIT for all images and documents (1MB, 20MB) or maybe not do it for the photos (but up to 5mb);
  21. */
  22. $range = 5000;/* UNCHANGEABLE VALUE! */ $sub_dir = ceil($r['id']/$range); $targetPath = $_SERVER['DOCUMENT_ROOT'].N.'i'.N.$sub_dir.N.$r['id'].N;
  23.  
  24. /** HERE IS SECURITY HOLE: VERIFY DO I CAN UPLOAD ANY SCRIPTS WITH .php or any other extensions not allowed anywhere in script ||||| handled? **/
  25. $fileTypes = str_replace('*.','',$_REQUEST['fileext']); $fileTypes = str_replace(';','|',$fileTypes); $typesArray = split('\|',$fileTypes); $fileParts = pathinfo(strtolower($_FILES['Filedata']['name']));
  26.  
  27. #$q = q('SELECT id FROM `'.PRFX.'ads_files` WHERE checksum = "'.md5_file($_FILES['Filedata']['tmp_name']).'" AND id_ = "'.$r['id'].'" LIMIT 1'); if(n_r($q) == 0) {
  28. q('INSERT INTO `'.PRFX.'ads_files` (id_,descr,th) VALUES ("'.$r['id'].'","","")'); $filename = $r['t_'].',(www.'.$cfg['t'].',ID#'.$r['id'].'),'.l_id().'.'.$fileParts['extension'];
  29. q('UPDATE `'.PRFX.'ads_files` SET t = "'.$filename.'" WHERE id = "'.l_id().'"');
  30. /* '.md5_file($_FILES['Filedata']['tmp_name']).' DON'T DO CHECKSUMS, IF USER WOULD FIND A DUPLICATE [doesn't check] HE WOULD DELETE IT; INSTEAD A FILENAME WOULD BE PUT, BECAUSE IT WAS BE USED TO DON'T READ ALL THE TIME FOLDERS (lower server usage) */
  31. $targetFile = str_replace('//','/',$targetPath).basename($filename);
  32.  
  33. if($fileParts['extension'] == 'gif' OR $fileParts['extension'] == 'jpeg' OR $fileParts['extension'] == 'png' OR $fileParts['extension'] == 'jpg' OR $fileParts['extension'] == 'jpg' OR $fileParts['extension'] == 'doc' OR $fileParts['extension'] == 'docx' OR $fileParts['extension'] == 'pdf') {
  34. if(in_array($fileParts['extension'],$typesArray)) {
  35. mkdir(str_replace('//','/',$targetPath),0755,true); move_uploaded_file($_FILES['Filedata']['tmp_name'],$targetFile);
  36.  
  37. include($_SERVER['DOCUMENT_ROOT'].'/libs/watermark/index.php'); if($fileParts['extension'] == 'gif' OR $fileParts['extension'] == 'jpeg' OR $fileParts['extension'] == 'png' OR $fileParts['extension'] == 'jpg')
  38. imagewatermark($targetFile,$_SERVER['DOCUMENT_ROOT'].'/libs'.N.'watermark/watermark.png',65);
  39.  
  40. switch($_FILES['Filedata']['error']) {
  41. case 1: die('The file is bigger than this PHP installation allows'); break;
  42. case 2: die('The file is bigger than this form allows'); break;
  43. case 3: die('Only part of the file was uploaded'); break;
  44. case 4: die('No file was uploaded'); break;
  45. case 6: die('Missing a temporary folder'); break;
  46. case 7: die('Failed to write file to disk'); break;
  47. case 8: die('File upload stopped by extension'); break;
  48. default: die('unknown error '.$_FILES['Filedata']['error']);
  49. } echo str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);
  50. } else die(H.'Invalid file type');
  51. }
  52. #}
  53. }
  54.  
  55. ?>
Go to the top of the page
+Quote Post
Helid
post 2.11.2011, 20:40:24
Post #2





Grupa: Zarejestrowani
Postów: 280
Pomógł: 20
Dołączył: 12.12.2007
Skąd: 127.0.0.1

Ostrzeżenie: (0%)
-----


Można ewentualnie zamienić imagewatermark na warunek if, który zwróci false w wypadku gdy plikiem nie będzie obrazek.


--------------------
Go to the top of the page
+Quote Post
Orzeszekk
post 2.11.2011, 20:54:29
Post #3





Grupa: Zarejestrowani
Postów: 260
Pomógł: 14
Dołączył: 8.09.2011

Ostrzeżenie: (0%)
-----


Moge się mylić ale na moje oko ten skrypt nie jest bezpieczny, co autor napisal nawet w komentarzach. Rozpoznaje rozszerzenie na podstawie rozszerzenia pliku, co mozna podrobic.

Jeśli dodasz warunek, że jeżeli nie uda się utworzyć miniatury (jeśli ktoś wyśle np. plik php z rozszerzeniem JPG) to usunie zuploadowany plik to będzie bezpieczniej.

Nie mozna polegac ani na rozszerzeniu pliku ani na typie mime, gdyz jedna i druga wartosc moze wprowadzic skrypt w błąd.
Ponadto, nic nie robisz z orginalnym plikiem (chyba - tak mi sie wydaje. Tworzysz miniature, a w galerii po kliknieciu miniatury normalnie wyswietlasz orginalny obraz?). Bezpieczniej jest wyciąć metadane z pliku, lub odczytać obraz, zmniejszyc go do rozsądnych rozmiarów biblioteka GD lub imagemagick i zapisac go na nowo - to tez wytnie metadane z pliku. Rozszerzenie nowemu plikowi nadajesz wedle rozpoznanego typu obrazka przez biblioteke GD - tego sie juz oszukac nie da bo odczytuje dane z tresci pliku.

Jeżeli ktos wrzuci ci do obrazka w komentarz kod PHP i uda mu sie podmienic .htaccess lub masz zle skonfigurowany serwer to w metadanych mozna przemycic kod PHP. Utworz obrazek gif, wpisz w komentarz kod <?php phpinfo(); ?>, tylko juz nie pamietam czy wystarczy go wrzucic w gif, czy trzeba zmienic mu rozszerzenie na php, w kazdym razie powinno ci wyskoczyc phpinfo.

po za tym pomyśl o jakichś limitach na upload (mozesz to trzymac w bazie danych i ujmowac gdy ktos zuploaduje plik od dziennego limitu dla usera) - zabezpieczy cie to przed zasypaniem serwera smieciami gdy wyjedziesz na tydzien na wakacje.

No i kolejna luka co juz pisze w komentarzach - pozwala na wrzucenie pliku dla innego uzytkownika.

Swoją drogą to chyba gotowiec - w takim razie wez solidny porządny skrypt a nie jakis szajs którego autorowi nawet nie chcialo sie pousuwac poważnych błędów.


--------------------
"The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time."
Tom Cargill, Bell Labs
Go to the top of the page
+Quote Post
AndyPSV
post 3.11.2011, 13:48:50
Post #4





Grupa: Zarejestrowani
Postów: 393
Pomógł: 5
Dołączył: 6.02.2003
Skąd: The.Luciferian.Doctrine.p
df

Ostrzeżenie: (30%)
XX---


napisalem swoj skrypt, czy teraz moglby ktos sprawdzic?

  1. $max_filesize = 4*1024*1024; $this->tpl->assign('max_filesize',$max_filesize); $this->tpl->assign('_sOFF',1);
  2. if(!empty($_FILES)) {
  3. $fileParts = pathinfo(strtolower($_FILES['file']['name'])); $targetFile = str_replace('//','/',$targetPath).basename($filename);
  4.  
  5. if($_FILES["file"]["size"] > $max_filesize) die(H.'filesize is beyond '.floor($max_filesize/1048576).'MB');
  6. if($_FILES["file"]["error"] == UPLOAD_ERR_OK) {
  7. if($fileParts['extension'] == 'gif' OR $fileParts['extension'] == 'jpeg' OR $fileParts['extension'] = 'png' OR $fileParts['extension'] = 'jpg') {
  8. @mkdir(str_replace('//','/',$targetPath),0755,true); move_uploaded_file($_FILES['file']['tmp_name'],$targetFile);
  9.  
  10. require_once 'libs/thumb/ThumbLib.inc.php';
  11. try { $thumb = PhpThumbFactory::create($targetPath.$filename); }
  12. catch (Exception $e) { }
  13.  
  14. $thumb->adaptiveResize(175,175);
  15. $thumb->save($targetPath.$filename,TH_EXT);
  16. exit(header(LOC.URL.$_GET[0].N.$_GET[1].N.$_GET[2]));
  17. } else die(H.'Invalid file type');
  18. } else die(H.'file upload error (probably filesize is beyond '.floor($max_filesize/1048576).'MB)');
  19. }
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.06.2025 - 07:29