Мы должны санировать $ _FILES ['имя файла'] ['имя']?

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

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

Спасибо

10
задан David 16 August 2011 в 19:51
поделиться

3 ответа

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

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

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

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 () , он добавляется к имени файла если и только если другой файл с таким же именем уже существует

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

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

6
ответ дан 4 December 2019 в 00:22
поделиться

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

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

5
ответ дан 4 December 2019 в 00:22
поделиться

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

1
ответ дан 4 December 2019 в 00:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: