Jörg Reinholz: Dateityp / Nime-Typ überschreiben

Beitrag lesen

Der Code sieht nun so aus:

<a title="meinbild" href="http://www.meinedomain.de/meinbild.jpg" download="meinneuerbildname.jpg">Linktext</a>


>   
> Nur leider ändert sich nichts, es wird immer noch auf das Bild verlinkt.  
  
Variante 1:  
===========  
  
Wenn der Server ein Apache ist \_und\_ so eingerichtet ist, dass die .htaccess beachtet wird ([allow ovrride](http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride)) \_und\_ wenn Du die Möglichkeit hast, die Namen der Bilder zu beeinflussen, dann könntest Du mit mit einer Datei .htaccess dafür sorgen, dass anhand des namens unterschieden wird:  
  
  
~~~apache
<FilesMatch ".*/download.*\.jpg$" >  
ForceType application/octet-stream  
</FilesMatch>

Alle Dateien, die mit download beginnen werden mit einem (angeblichen) Dateityp "application/octet-stream" angeboten, der Browser wird diese zum Download anbieten. Es gänge z.B. auch mit 'file/safe-me' - weil der Browser alle unbekannten Dateitypen zum Download anbietet.

Variante 2:

Wenn der Server ein Apache ist _und_ so eingerichtet ist, dass die .htaccess beachtet wird (allow ovrride) _und_ wenn Du die Möglichkeit hast, den Ordner zu beeinflussen, in dem die auszuliefernden Bilder liegen, dann könntest Du ebenfalls mit mit einer Datei .htaccess dafür sorgen, dass anhand des Ordners unterschieden wird:

Datei .htaccess im Wurzelordner oder als Teilstück direkt in der Serverkonfiguration, normalerweise: /etc/apache2/sites-enabled/[IRGEND_EIN_NAME].conf

<Location /downloads>  
ForceType unknown/unknown  
</Location>  

Datei .htaccess  im Ordner /downloads/:
ForceType download/safe-me

Variante 3:

Mit PHP:
Ein skript sorgt dafür, dass die Datei mit einem passenden Dateityp ausgeliefert wird. Das muss aber auch dafür sorgen, dass durch Manipulation nicht etwa z.B. die Datei /etc/passwd oder etc/groups oder eien sonstige nicht vorgesehene Datei ausgeliefert wird. Dazu bestimmt man den Ordner und sorgt dafür, dass die übermittelten Dateinamen nicht etwa '..' enthalten oder PHP-Skripte sind.

Als Adresse gib etwas wie: 'download.php?filename=the_fine_pic.jpg' an.

Die download.php

<?php  
  
# Anpassen:  
define('DOWNLOAD_DIR', '/srv/www/downloads/');  
define('MIME_TYP', 'bin/unknown');  
  
# Mindestausstattung! Eventuell weitere Prüfungen einbauen,  
/*  
Verboten werden Zugriffe auf Dateien, die  
- im Name etwas wie '../' enthalten - Zugriffe auf Ordner oberhalb von DOWNLOAD_DIR - wahlfreier Zugriff im Dateisystem  
- mit '/' beginnen  - wahlfreier Zugriff im Dateisystem  
- mit einem Punkt beginnen (versteckte Dateien wie z.B. .htaccess)  
- mit der Endung php  
- mit der Endung pl  
- die im Name etwas wie ':/' enthalten (Zugriff auf entfernte Dateisysteme!)  
- groß/klein ist irrelevant, es wird nach beiden gesucht.  
*/  
$arForbiddenStrings=array(  
  '\.\.\/',  
  '^\/',  
  '^\.',  
  '\.php$',  
  '\.php',  
  '\.pl$',  
  ':\/'  
);  
  
# Programm:  
  
if (! isset($_GET['filename'])) {  
     header('HTTP/1.1 404 NOT FOUND');  
     header('Content-Type:text/html');  
     print '<h1>Es fehlen Informationen.</h1>';  
     exit;  
}  
  
  
foreach ($arForbiddenStrings as $s) {  
   if ( preg_match('/'.$s.'/i', $_GET['filename']) ) {  
      header('HTTP/1.1 403 FORBIDDEN');  
      header('Content-Type:text/html');  
      print '<h1>Zugriff verboten!</h1>';  
      exit;  
   }  
}  
  
  
$filename=DOWNLOAD_DIR . str_replace('..', $_GET['filename']);  
if (is_file($filename) && is_readable($filename)) {  
     header('Content-Type: ' . MIME_TYP);  
     passthru($filename);  
     exit;  
} else {  
     header('HTTP/1.1 404 NOT FOUND');  
     header('Content-Type:text/html');  
     print '<h1>Nicht gefunden!</h1>';  
     exit;  
}  

Das das ?> fehlt ist hier nicht nur völlig in Ordnung, sondern sogar Absicht.
Es ist kein Problem, sondern oft wünschenswert, wenn der Download-Ordner außerhalb des Dokument-Root liegt. Allerdings muss man sich dann im klaren sein, dass alle (nicht versteckten, also nicht mit einem Punkt beginnenden) Dateien, die mit Leserechten für jeden oder den Webserver versehen sind, dann auch ausgeliefert werden. Das könnte verwirren.

Jörg Reinholz