Галерея изображений PHP (проблема загрузки) - PullRequest
0 голосов
/ 30 декабря 2010

Вероятно, это простой вопрос, однако мне трудно его выполнить.

У меня есть класс php (код "class.upload.php" ниже *), который вызывается с помощью:

<?php 
    $upload = new upload(); 
    $upload->upload_file();
?>

так на тестовой странице это было бы так:

<?php 
    $upload = new upload(); 
    $upload->upload_file(); 
?>


<form action="" method="post" enctype="multipart/form-data">
    <input type="file" id="real_upload" class="hide" name="file" />
    <input type="submit" id="real_submit" class="hide" value="Upload" />
</form>

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

    <?php

    $mysql_link = mysql_connect("localhost", "", "");   
        mysql_select_db("") or die("Could not select database");

        while($counter <= count($photos_uploaded)) {
            if($photos_uploaded['size'][$counter] > 0) {
                if(!array_key_exists($photos_uploaded['type'][$counter], $known_photo_types)) {
                    $result_final .= "File ".($counter+1)." is not a photo<br />";
                }
                else {
                    mysql_query( "INSERT INTO gallery_photos(`photo_filename`, `photo_caption`, `photo_category`) VALUES('0', '".addslashes($photo_caption[$counter])."', '".addslashes($_POST['category'])."')" );
                    $new_id = mysql_insert_id();
                    $filetype = $photos_uploaded['type'][$counter];
                    $extention = $known_photo_types[$filetype];
                    $filename = $new_id.".".$extention;

                    mysql_query( "UPDATE gallery_photos SET photo_filename='".addslashes($filename)."' WHERE photo_id='".addslashes($new_id)."'" );
 }

    ?>

Как бы я подошел к этому?

Спасибо, Кейран

class.upload.php

<?php
class Upload {
    //File Max Size:
    protected $max_file_size = 5;

    public function upload_file() {
        //Check for upload request:
        if(isset($_FILES['file'])) {
            //Set File Information:
            $file = array(
                'name' => $_FILES['file']['name'],
                'type' => $_FILES['file']['type'],
                'size' => $_FILES['file']['size'],
                'temp' => $_FILES['file']['tmp_name'],
                'error' => $_FILES['file']['error']
            );

            //Check if it is under the max size limit
            if($file['size'] < ($this->max_file_size * 1048576)) {

            //Filename:
                $filename = strtolower($file['name']);
                $filename = str_replace(" ","_",$filename);

                //Check for a custom path location, if none exists it will load into a file associated directory
                if (isset($_REQUEST['customPath'])) {
                    $path = 'uploads/'.$_REQUEST['customPath'].'/';
                } else {
                    $path = 'uploads/'.$file['type'].'/';
                        if(!file_exists($path) && !is_dir($path)) {
                            mkdir($path, "511", true);
                        }
                }

                //Now lets more the file:
                $move_file = move_uploaded_file($file['temp'], $path . $filename);

                if($move_file) {
                    echo 'uploads/'.$filename;
                }
            } else {
                echo 'Your file is too big to upload to our server.';
            }
        }
    }
}

?>

1 Ответ

1 голос
/ 30 декабря 2010

Ваш класс загрузки открывает ваш сервер для полного компромисса.

  1. Вы не дезинфицируете поле customPath и используете его вслепую как часть "куда я помещаю этот файл"дорожка.Злонамеренный пользователь может ввести относительный путь, и ваш сценарий с радостью попытается записать загруженный файл ЛЮБОЕ на вашем сервере
  2. . Вы не проверяете наличие конфликтов имен файлов, поэтому злонамеренный пользователь может объединить уязвимость №1 с этим и вашимскрипт с радостью перезапишет любой файл, к которому у веб-сервера есть доступ.Хотя (я надеюсь) ваш сервер не работает от имени пользователя root, рассмотрите customPath ../../../../../../../../../../etc/ и загруженное имя файла passwd, что заставит ваш веб-сервер перезаписать /etc/passwd предоставленной пользователем версией.
  3. Параметр size в массиве $ _FILES также предоставляется пользователем и может быть легко подделан.Злонамеренный пользователь может установить его на 1 и загрузить файл размером в несколько терабайт, если он того пожелает.Вместо этого лучше определить фактический размер файла с помощью filesize($_FILES['file']['tmp_name']).
  4. Проверка isset($_FILES['file']) недостаточна для определения, был ли файл действительно загружен.Запись file будет воссоздана в ЛЮБОЕ ВРЕМЯ, а <input type="file" name="file"> присутствует в форме, независимо от того, была ли загрузка успешной или нет.Вы должны проверить ($_FILES['file']['error'] === UPLOAD_ERR_OK), чтобы увидеть, была ли загрузка успешной или нет (константы ошибок определены здесь )
  5. Часть type массива $ _FILES также является пользовательскойпоставляется и может быть подорван.Ничто не мешает злоумышленнику установить значение image/jpeg, но при этом загружать nasty_virus_from_hell.exe на ваш сервер.Вы должны использовать getimagesize() или FileInfo() для безопасного определения типа MIME.
  6. addslashes() - очень плохой метод очистки данных для вставки SQL-запросов.Это НЕ безопасный метод, используйте mysql_real_escape_string(), который использует собственный API MySQL для выполнения очистки и делает это таким образом, чтобы быть гарантированно безопасным для MySQL.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...