Проверка типов файлов при загрузке и проблем с зависимостями браузера - PullRequest
3 голосов
/ 08 января 2010

Я создаю загрузчик php-файлов, и у меня есть некоторые проблемы с безопасностью. Например, я не хочу разрешать загрузку файлов ".php". Как я знаю, единственный способ проверить тип файла - это $_FILES['file']['type'], а его значение зависит от браузера.

Я проверил несколько браузеров и обнаружил, что при выборе обычного .php-файла разные браузеры возвращают следующие значения:

firefox: application/x-download
chrome: text/plain
safari: text/plain
IE: text/plain
opera: application/octet-stream

Я также пытался провести тот же эксперимент с обычными файлами .txt, и все браузеры возвращают text/plain как тип mime.

Так вот в чем проблема: если я хочу разрешить загрузку файла .txt, что мне следует сделать, чтобы предотвратить загрузку файла .php?

Ответы [ 3 ]

3 голосов
/ 08 января 2010

Не полагайтесь на информацию, которую отправляет клиент. Даже тип носителя, который отправляет клиент, может быть подделан.

Если вы не хотите разрешать файлы PHP, просто не разрешайте файлы с расширением .php или измените его на .txt:

if (strtolower(strrchr($_FILES['file']['name'], '.')) == '.php') {
    // has file extension .php
}
2 голосов
/ 11 января 2010

Используйте следующую функцию:

function Mime($path)
{
    $result = false;

    if (is_file($path) === true)
    {
        if (function_exists('finfo_open') === true)
        {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);

            if (is_resource($finfo) === true)
            {
                $result = finfo_file($finfo, $path);
            }

            finfo_close($finfo);
        }

        else if (function_exists('mime_content_type') === true)
        {
            $result = preg_replace('~^(.+);.*$~', '$1', mime_content_type($path));
        }

        else if (function_exists('exif_imagetype') === true)
        {
            $result = image_type_to_mime_type(exif_imagetype($path));
        }
    }

    return $result;
}

Это вернет правильный тип MIME любого файла.

0 голосов
/ 08 января 2010

Попробуйте следующее. Это далеко от дурака, но это быстрая проверка. он будет блокировать все, что помечено .php (как на клиентском компьютере), поэтому, если у них есть что-то вроде 'do_evil.php.txt', это будет разрешено, НО (прочитайте примечания к коду)

$file_ext = substr($_FILES['userfile']['name'], -3);
if($file_ext == 'php') {
   //REJECT FILE
}
else {
   // allow upload and once the file has been upload to the temp directory
   // have a peice of code move the file to the final location and rename 
   // the file and specify a new file extension, using $file_ext as the extension
   // so even if the file was 'do_evil.php.txt' when it comes to rest at the 
   // final location it will be 'do_evil.txt' and thus treated by the server as a
   // text file and not PHP
}

Я использовал вышеупомянутое в прошлом с результатами снижения. Это ни в коем случае не пулевое доказательство, но это должно, по крайней мере, помочь. я думаю, что у меня может быть какой-то код, который делает все это, если вам это нужно, я буду искать его, но без обещаний я могу его найти

...