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

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

1. Всегда проверяйте тип файла и тип MIME.

Никогда не доверяйте расширениям, предоставляемым клиентом, или простым проверкам заголовков MIME. Злоумышленники могут легко переименовать скрипт   .php   в   .jpg   или подделать заголовок  Content-Type  во время передачи запроса.

Используйте встроенные правила проверки Laravel в специальных   запросах формы , чтобы строго соблюдать расширения, типы MIME на основе содержимого и ограничения на размер файлов:

PHP Artisan make: запрос StoreDocumentRequest

StoreDocumentRequest.php

 
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreDocumentRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'document' => [
                'required',
                'file',
                'mimes:pdf,png,jpg,jpeg',        // Enforces allowed extension mapping
                'mimetypes:application/pdf,image/png,image/jpeg', // Checks file signature/magic bytes
                'max:5120',                      // Restricts size to 5MB (in kilobytes)
            ],
        ];
    }
}

 

Полезное правило: комбинируйте мимов и мимотипов. Правило mimetypes использует расширение PHP Fileinfo для анализа двоичного содержимого файла, а не полагается на расширение файла клиента.

2. Никогда не храните файлы напрямую в общедоступном каталоге.

Основная ошибка новичков — сохранение загрузок в общедоступном каталоге или прямое создание исполняемых файлов на веб-сервере. Если пользователь загружает вредоносный PHP-скрипт и нажимает на его прямой URL-адрес, сервер может его выполнить.

 storage/
└── app/
    ├── private/    <-- Secure: Unaccessible via direct public URLs
    └── public/     <-- Symlinked to public/storage (Only for public media)

 

3. Генерируйте случайные, непредсказуемые имена файлов

Использование исходного имени файла, предоставленного клиентом, открывает ваше приложение для:

  • Атаки обхода пути (../../etc/passwd или перезапись существующих файлов).
  • Конфликты имен файлов (когда два пользователя загружают файл счета-фактуры.pdf).
  • Утечки конфиденциальности (раскрытие внутренних пользовательских схем именования файлов).

Метод store() в Laravel автоматически генерирует уникальный криптографически безопасный хэш для имени файла:

 namespace App\Http\Controllers;

use App\Http\Requests\StoreDocumentRequest;
use Illuminate\Http\RedirectResponse;

class DocumentController extends Controller
{
    public function store(StoreDocumentRequest $request): RedirectResponse
    {
        // Automatically generates a hash name like "a8f3b2c...jpg"
        $path =$request->file('document')->store('documents', 'private');

        // Preserve original metadata safely in database if needed
        auth()->user()->documents()->create([
            'path' => $path,
            'original_name' => $request->file('document')->getClientOriginalName(),
            'mime_type' => $request->file('document')->getClientMimeType(),
            'file_size' => $request->file('document')->getSize(),
        ]);

        return back()->with('success', 'Document uploaded securely.');
    }
}

 

4. Безопасная передача файлов через временные подписанные URL-адреса.

При хранении на частном диске или в частной корзине S3 файлы защищены от несанкционированного публичного скачивания. Чтобы разрешить авторизованным пользователям просматривать или загружать файл, создайте временный подписанный URL-адрес:

В вашем контроллере или ресурсе API:

 use Illuminate\Support\Facades\Storage;

public function show(Document $document)
{
    // Ensure the authenticated user owns or has access to the document
    $this->authorize('view',$document);

    // Creates a temporary download URL valid for 15 minutes
    $url = Storage::disk('s3')->temporaryUrl($document->path,
        now()->addMinutes(15)
    );

    return response()->json(['download_url' => $url]);
}

 

5. Удалить метаданные и очистить изображения

Изображения, загруженные непосредственно со смартфонов, содержат метаданные EXIF ​​(координаты GPS, модель камеры, временная метка). Если публичные пользователи могут просматривать эти изображения, это представляет значительный риск для конфиденциальности.

Используйте пакеты, такие как Intervention/image, для перекодирования загруженных изображений и удаления конфиденциальных метаданных перед сохранением:

 
use Intervention\Image\Laravel\Facades\Image;
use Illuminate\Support\Facades\Storage;

public function uploadAvatar($request)
{
    $file =$request->file('avatar');

    // Read and strip EXIF by re-encoding
    $image = Image::read($file)->encodeByExtension('webp', quality: 80);

    $fileName = 'avatars/' . Str::uuid() . '.webp';

    Storage::disk('public')->put($fileName, (string)$image);

    return $fileName;
}

 

Сводный контрольный список для производства

  • [ ] Проверка размера и типа: используйте как MIME, так и MIME-типы с явными ограничениями размера в байтах.
  • [ ] Рандомизация имен файлов: позвольте Laravel генерировать хеш-имена или используйте Str::uuid().
  • [ ] Хранить конфиденциально: используйте частные диски для конфиденциальных файлов; избегайте неконтролируемых общедоступных/каталогов.
  • [ ] Удаление метаданных: перекодирование пользовательских изображений для удаления данных EXIF/местоположения.
  • [ ] Ограничение скорости загрузки: примените промежуточное программное обеспечение throttle:upload для предотвращения DoS-атак.

Нужна масштабируемая веб- и облачная архитектура?

Создание готовых к использованию серверных платформ требует пристального внимания к безопасности, обработке файлов и масштабируемой архитектуре.

👉 Станьте партнером Software Solutions для индивидуальной разработки PHP и Laravel, развертывания в облаке, системной интеграции и разработки программного обеспечения с учетом ваших бизнес-целей.

Как вы управляете безопасной загрузкой файлов и личным хранилищем в своих проектах Laravel? Поделитесь своими стратегиями в комментариях ниже!