upload image sicher ??

hups1803

Erfahrenes Mitglied
ich habe folgende upload funktion:

PHP:
function uploadFile ($file_field = null, $check_image = false, $random_name = false) {
 
  //Config Section 
  //Set file upload path
  $path = 'uploads/user/'; //with trailing slash
  //Set max file size in bytes
  $max_size = 1000000;
  //Set default file extension whitelist
  $whitelist_ext = array('jpg','png','gif');
  //Set default file type whitelist
  $whitelist_type = array('image/jpeg', 'image/png','image/gif');

  //The Validation
  // Create an array to hold any output
  $out = array('error'=>null);
 
  if (!$file_field) {
  $out['error'][] = "Please specify a valid form field name"; 
  }

  if (!$path) {
  $out['error'][] = "Please specify a valid upload path"; 
  }
 
  if (count($out['error'])>0) {
  return $out;
  }

  //Make sure that there is a file
  if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) {
 
  // Get filename
  $file_info = pathinfo($_FILES[$file_field]['name']);
  $name = $file_info['filename'];
  $ext = $file_info['extension'];
 
  //Check file has the right extension 
  if (!in_array($ext, $whitelist_ext)) {
  $out['error'][] = "Invalid file Extension";
  }
 
  //Check that the file is of the right type
  if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
  $out['error'][] = "Invalid file Type";
  }
 
  //Check that the file is not too big
  if ($_FILES[$file_field]["size"] > $max_size) {
  $out['error'][] = "File is too big";
  }
 
  //If $check image is set as true
  if ($check_image) {
  if (!getimagesize($_FILES[$file_field]['tmp_name'])) {
  $out['error'][] = "Uploaded file is not a valid image";
  }
  }

  //Create full filename including path
  if ($random_name) {
  // Generate random filename
  $tmp = str_replace(array('.',' '), array('',''), microtime());
 
  if (!$tmp || $tmp == '') {
  $out['error'][] = "File must have a name";
  } 
  $newname = $tmp.'.'.$ext; 
  } else {
  $newname = $name.'.'.$ext;
  }
 
  //Check if file already exists on server
  if (file_exists($path.$newname)) {
  $out['error'][] = "A file with this name already exists";
  }

  if (count($out['error'])>0) {
  //The file has not correctly validated
  return $out;
  }

  if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) {
  //Success
  $out['filepath'] = $path;
  $out['filename'] = $newname;
  return $out;
  } else {
  $out['error'][] = "Server Error!";
  }
 
  } else {
  $out['error'][] = "No file uploaded";
  return $out;
  } 
}

nun habe ich ein image gehackt zum testen (ein auschnitt):
hackforum.png

und über diese datei getestet

PHP:
require_once("uploads/user/test.jpg");

leider lädt die upload funktion das file trotzdem hoch.

in der htacess habe ich

PHP:
php_flag engine 0
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
<IfModule mod_php5.c>
  php_flag engine off
</IfModule>
ForceType application/octet-stream
<FilesMatch "(?i)\.jpe?g$">
  ForceType image/jpeg
</FilesMatch>
<FilesMatch "(?i)\.gif$">
  ForceType image/gif
</FilesMatch>
<FilesMatch "(?i)\.png$">
  ForceType image/png
</FilesMatch>

ich kann die datei ausführen !!!

das ergebnis aus der require_once ist

ÿØÿàJFIF,,ÿþ,-- Hello, friend from 31.18.188.4! A lovely Friday morning, isn't it?uploads/user/0432049001413499597.jpg
 
Hi,

natürlich geht das, du sagst ja PHP explizit, dass es das Bild als Script einbinden und ausführen soll.
Das .htaccess greift nur, wenn du die Datei direkt über den Browser aufrufst, also z.B.: http://example.com/bilder/test.jpeg

Du kannst das Bild hochladen, weil es noch immer ein gültiges JPEG-Bild ist. Den Text, oder Code den du meinst, der steht rein als "Kommentar" in dem Bild drin. In diesen EXIF-Daten können beliebige Texte stehen.

Solange du also nirgends anders PHP-Scripte hochladen lässt sollte das so passen. Wenn du das trotzdem filtern willst, dann musst du das Bild auf dem Server neu laden und anschließend speichern. Dann löscht er alle EXIF-Daten raus: https://stackoverflow.com/questions/3614925/remove-exif-data-from-jpg-using-php


Grüße,
BK
 
Zurück