2008-09-24 9 views
0

est-il un moyen d'empêcher quelqu'un de faire semblant un type MIME sur un téléchargement de fichier, puis l'exécution d'un php/exe/etc ...éviter mime trucage sur les téléchargements php

Je dois rendre le répertoire de téléchargement de fichiers inscriptible et exécutable afin que les fichiers peuvent être stockés, mais cela permet à quiconque d'exécuter un script après. Une chose que je peux faire est d'ajouter des données aléatoires au nom du fichier afin qu'ils ne puissent pas deviner le nom du fichier après (puisqu'ils ne peuvent toujours pas lire dans le répertoire pour obtenir une liste). J'utilise le téléchargement de fichiers avec php pour la première fois et j'essaie de couvrir tous les problèmes de sécurité.

Répondre

2

Le répertoire de téléchargement de fichiers ne doit pas être accessible au navigateur Web. C'est à dire. ne laissez pas quelqu'un télécharger un fichier, dites "remove_all_my_files.php", puis exécutez-le sur votre système en lui donnant l'URL, dites "http://xample.com/uploads/remove_all_my_files.php".

+0

Donc, tant que je ne permets pas quoi que ce soit avec .php et Occultation le nom du fichier que je devrais être correct. – dbrien

+0

Non, ce qu'il veut dire, c'est de télécharger les fichiers au dessus de votre répertoire "www" ou public_html. c'est-à-dire quelque chose que votre serveur peut accéder, mais n'a pas d'URL directe. – Swati

+0

Il est plus sûr de ne pas autoriser l'accès http à ce répertoire que de se fier à toutes les différentes extensions de fichiers dangereuses. Rappelez-vous ce que c'était un choc quand les gens ont découvert toutes les extensions de fichiers que Windows exécuterait? –

0

Les informations de $_FILES proviennent toujours du client, ce que vous voulez faire est d'accepter le fichier et de le scanner sur le serveur. Je recommande d'utiliser soit finfo, qui est une extension PHP et il est facile:

<?php 
// example :-) 
$finfo = finfo_open(FILEINFO_MIME); 
echo finfo_file($finfo, '/path/to/your/upload/file); 
finfo_close($finfo); 
?> 

Il y a aussi un OO-interface si vous n'aimez pas la procédure.

Si finfo n'est pas une option, vous pouvez utiliser la commande unix file pour vérifier.

En outre, de nombreuses personnes suggèrent de servir des fichiers via un wrapper. Je suis déchiré sur celui-ci, il peut être une solution mais c'est loin d'être idéal car a) les fichiers sont toujours sur votre serveur et b) il est coûteux de servir des fichiers comme ça.

-1

Sur mes configurations de serveur Web Apache, je ne crois pas que le contenu réel du fichier détermine si un fichier s'exécute en tant que script ou non. La détermination de l'affichage d'un fichier au format texte ou image ou de l'exécution en tant que script s'effectue en faisant correspondre la fin du fichier.

Par exemple, une directive dans le fichier de configuration apache, httpd.conf de

AddType application/x-httpd-php .php

indique au serveur d'exécuter des fichiers se terminant par .php pour fonctionner comme un script PHP. Assurez-vous donc qu'aucun des fichiers téléchargés n'est enregistré avec une fin .php, ou toute autre fin exécutable de script ou toute fin de fichier que vous utilisez pour les fichiers d'inclusion.

+0

Avec un appel shell, vous pouvez exécuter (= exécuter) n'importe quoi. Ou faire fonctionner n'importe quoi. Vous pouvez également exécuter .txt. L'extension de fichier n'a pas d'importance. C'est une chose Windows où les gens assument.exe fonctionne, il s'agit vraiment d'autorisations. – Till

+0

Dans le contexte d'une application Web, où allez-vous obtenir l'interpréteur shell pour faire cet appel? Vous auriez besoin d'un accès shell pour le faire, n'est-ce pas? Vous ne pouvez pas simplement pointer un navigateur Web sur un script shell ou un script php et le dire "partez" sans que le serveur Web ne soit configuré pour autoriser cela –

+0

Vous avez déjà entendu parler de XSS? – Till

0

Ne pas servir le fichier directement. Conservez les téléchargements dans un emplacement d'accès non public. Lire à partir du fichier, tampon pour la sortie pour permettre le téléchargement.

est ici l'idée de base:

function ReadAndOutputFileChunked ($filename) { 
    $chunksize = 1*(1024*1024); // how many bytes per chunk 
    $buffer = ''; 
    $handle = @fopen($filename, 'rb'); 
    if ($handle === false) { 
     return false; 
    } 
    while (!feof($handle)) { 
     $buffer = @fread($handle, $chunksize); 
     print $buffer; 
    } 
    return @fclose($handle); 
} 

header("Content-type: application/octet-stream"); 
ReadAndOutputFileChunked('/private/path/to/upload/files/' . $nameOfFile); 
Questions connexes