Должны ли мы дезинфицировать $ _FILES ['filename'] ['name']? - PullRequest
10 голосов
/ 03 августа 2010

После того, как пользователь загрузит изображение на сервер, мы должны очистить $_FILES['filename']['name']?

Я проверяю размер файла / тип файла и т. Д. Но я не проверяю другие вещи. Есть ли потенциальная дыра в безопасности?

Спасибо

Ответы [ 3 ]

6 голосов
/ 03 августа 2010

Абсолютно! Как уже упоминал @Bob, слишком просто перезаписать общие имена файлов.

Есть также некоторые проблемы, которые вы можете решить, например, не всеразрешенные символы в Windows разрешены в * nix, и наоборот.Имя файла может также содержать относительный путь и потенциально может перезаписать другие не выгруженные файлы.

Вот метод Upload(), который я написал для PHP-фреймворка phunction :

function Upload($source, $destination, $chmod = null)
{
    $result = array();
    $destination = self::Path($destination);

    if ((is_dir($destination) === true) && (array_key_exists($source, $_FILES) === true))
    {
        if (count($_FILES[$source], COUNT_RECURSIVE) == 5)
        {
            foreach ($_FILES[$source] as $key => $value)
            {
                $_FILES[$source][$key] = array($value);
            }
        }

        foreach (array_map('basename', $_FILES[$source]['name']) as $key => $value)
        {
            $result[$value] = false;

            if ($_FILES[$source]['error'][$key] == UPLOAD_ERR_OK)
            {
                $file = ph()->Text->Slug($value, '_', '.');

                if (file_exists($destination . $file) === true)
                {
                    $file = substr_replace($file, '_' . md5_file($_FILES[$source]['tmp_name'][$key]), strrpos($value, '.'), 0);
                }

                if (move_uploaded_file($_FILES[$source]['tmp_name'][$key], $destination . $file) === true)
                {
                    if (self::Chmod($destination . $file, $chmod) === true)
                    {
                        $result[$value] = $destination . $file;
                    }
                }
            }
        }
    }

    return $result;
}

Важными частями являются:

  1. array_map('basename', ...), это гарантирует, что файл не содержит относительных путей.
  2. ph()->Text->Slug(), это обеспечивает только.0-9a-zA-Z допускается в имени файла, все другие символы заменяются подчеркиванием (_)
  3. md5_file(), это добавляется к имени файла если * другой файл с таким жеимя уже существует

Я предпочитаю использовать предоставленное пользователем имя, поскольку поисковые системы могут использовать его для получения лучших результатов, но если это не важно для вас, простой microtime(true) или md5_file() может упроститьнемного.

Надеюсь, это поможет!=)

4 голосов
/ 03 августа 2010

Имя файла - произвольная строка, предоставленная пользователем. Как правило, никогда не доверяйте произвольным предоставленным пользователем значениям.

Вы никогда не должны использовать предоставленное пользователем имя файла в качестве имени для сохранения файла на сервере, всегда создавайте свое собственное имя файла. Единственное, что вы можете захотеть сделать с этим, - это сохранить его как метаданные для информационных целей. При выводе этих метаданных примите обычные меры предосторожности, такие как санитария и побег.

1 голос
/ 03 августа 2010

Вам также необходимо проверить наличие дубликатов имен. Несколько человек слишком легко загружают изображение с именем «mycat.jpg», которое при загрузке в одну и ту же папку перезаписывает ранее загруженный файл с тем же именем. Вы можете сделать это, вставив уникальный идентификатор в имя файла (как предлагает Prix). Также убедитесь, что тип файла не только заканчивается расширением изображения, но также является фактическим изображением; вы не хотите, чтобы ваш сервер действовал как слепой хост для случайных файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...