Form multipart form data php: POST запрос, составное содержимое (multipart/form-data) / Хабр

Missing boundary in multipart/form-data — блог Игоря Звягинцева

Лирическое вступление

Чтобы писать посты в блог нужен редактор. Чтобы посты читали в них нужно добавлять картинки. Чтобы добавлять картинки в посты в редакторе должна быть кнопка «Добавить картинку». И она у меня есть, но, как в том анекдоте, есть один нюанс* и состоит он в том, что редактор постов является самописным Vue приложением в основе которого Vue2Editor который, в свою очередь, построен вокруг редактора Quill (говно, не используйте). Как следствие самописности, реализация таких вещей как загрузка картинок начиная от выбора картинки с помощью диалогового окна или драг-н-дропа до отправки её на сервер ложатся на мои плечи.

Самая суть

Итак, у меня есть код, который загружает картинку на сервер.

handleImageAdded: async function(file) {
    if (!file) return
    const formData = new FormData()
    formData.append('image', file)
    const headers = new Headers({
        'Content-Type': 'multipart/form-data',
        user: /* имя пользователя */,
        token: /* токен пользователя */
    })
    try {
        const result = await fetch(
            '/api/endpoint/for/image',
            {
                headers,
                method: 'POST',
                body: formData
            }
        )
        const url = result. data.url
        // … код вставки картинки в пост
    } catch (error) {
        console.error(error)
    }
}

Кто понял где тут ошибка, тот молодец и дальше может не читать.

Тем, кто не понял скажу, что источник проблемы в отправляемых заголовках. Точнее в Content-Type. Далее в нескольких предложениях я рефлексирую на тему как я допустил такую ошибку. Если вы не любите воду в блогах, то листайте до подзаголовка «Решение»

Посыпаю голову пеплом

Мой основной язык это JavaScript. В последний раз на PHP много лет назад и, когда, в своём переписывании движка сайта с нуля, я дошёл до необходимости загрузить файл на сервер. Я естественно вбил в гугл «PHP загрузка файлов». Первая же ссылка привела меня сюда. Если взглянуть на форму из Примера №1, то можно увидеть, что в тэге <form> указаны несколько свойств. Если они указаны в самом первом примере, рассудил я, который, по идее, должен быть самым простым и минимально рабочим, значит надо их явно передавать. Тем более там первой строчкой идёт комментарий с КАПСЛОКОМ где выделены слова ДОЛЖЕН БЫТЬ. Логично? Логично! А вот и нет!

Решение

Проблема в заголовке Content-Type. Он есть. Он правильный, но с ним что-то не так. Что?

Не так с ним то, что он не полон. Если не устанавливать его в коде, то браузер выставит его самостоятельно и выглядеть он будет вот так:

То есть, даже если мы программно выгружаем файл, то умница-браузер всё равно сам подставит правильный заголовок за нас. Как говаривали на Руси: —«Не лезь вперёд батьки в пекло!». Очень мудрые слова.

Итого есть два стула: на одном вам придётся руками ставить Content-Type и boundary. Это сложно, долго и бессмысленно. На втором вам просто нужно не добавлять заголовок в коде. Выбор за вами.

К столь простому решению меня привёл вот этот комментарий

______

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

HTML-форма enctype Атрибут

❮ Тег HTML

Пример

Отправить данные формы, закодированные как «multipart/form-data»:


 
 


 



  <ввод type="submit" value="Submit">

Попробуйте сами »


Определение и использование

Атрибут enctype указывает, как данные формы должны быть закодированы, когда отправив его на сервер.

Примечание: Атрибут enctype можно использовать, только если метод = "пост" .


Поддержка браузера

Атрибут
enctype Да Да Да Да Да

Синтаксис

Значения атрибутов
Значение Описание
приложение/x-www-form-urlencoded По умолчанию. Все символы кодируются перед отправкой (пробелы преобразуются в символы «+», а специальные символы преобразуются в значения ASCII HEX)
multipart/form-data  Это значение необходимо, если пользователь будет загружать файл через форма
текстовый/обычный Отправляет данные вообще без какой-либо кодировки. Не рекомендуется

❮ Тег HTML


НАБОР ЦВЕТА



Лучшие учебники
Учебное пособие по HTML
Учебное пособие по CSS
Учебное пособие по JavaScript
Учебное пособие
Учебник по SQL
Учебник по Python
Учебник по W3.CSS
Учебник по Bootstrap
Учебник по PHP
Учебник по Java
Учебник по C++
Учебник по jQuery

Лучшие ссылки
HTML Reference
CSS Reference
JavaScript Reference
SQL Reference
Python Reference
W3.CSS Reference
Bootstrap Reference
PHP Reference
HTML Colors
Java Reference
Angular Reference
jQuery Reference

901 00 Лучшие примеры Примеры HTML
Примеры CSS
Примеры JavaScript
Примеры инструкций
Примеры SQL
Примеры Python
Примеры W3. CSS
Примеры Bootstrap
Примеры PHP
Примеры Java
Примеры XML
Примеры jQuery


ФОРУМ | О

W3Schools оптимизирован для обучения и обучения. Примеры могут быть упрощены для улучшения чтения и обучения. Учебники, ссылки и примеры постоянно пересматриваются, чтобы избежать ошибок, но мы не можем гарантировать полную правильность всего содержания. Используя W3Schools, вы соглашаетесь прочитать и принять наши условия использования, куки-файлы и политика конфиденциальности.

Copyright 1999-2023 Refsnes Data. Все права защищены.
W3Schools работает на основе W3.CSS.

Отказ в обслуживании PHP multipart/form-data — Уязвимости

Описание

Это предупреждение было создано с использованием только информации баннера. Это может быть ложное срабатывание.

Когда вы отправляете запрос POST скрипту PHP с типом содержимого multipart/form-data и включаете в этот запрос список файлов, PHP создаст временный файл для каждого файла из запроса. PHP создаст эти файлы независимо от того, может ли скрипт обрабатывать загрузку файлов или нет. После выполнения скрипта временные файлы будут удалены. Проблема в том, что в запрос можно включить очень большое количество файлов. PHP должен будет создать эти файлы до того, как скрипт будет выполнен, а затем удалить их.

Состояние отказа в обслуживании появляется, когда вы создаете кучу запросов, каждый из которых содержит большое количество (15000+) файлов. Когда вы отправляете эти запросы на веб-сервер, веб-сервер падает и перестает отвечать, потому что ему нужно обработать (создать и удалить) безумное количество файлов за очень короткий период времени. Любой веб-сайт, работающий под управлением PHP и на котором включена загрузка файлов (что является конфигурацией по умолчанию), уязвим. Вам не нужно иметь сценарий загрузки файла.

Затронутые версии PHP (до 5.3.0).

Исправление

Обходные пути:
1. Отключить загрузку файлов
Если вам не нужна загрузка файлов, вы можете отключить эту функцию в php. ini
file_uploads = Off
2. Установите PHP 5. 3.1
Если вы не можете отключить загрузку файлов на своем сайте, рекомендуется установить последнюю версию PHP. PHP 5.3.1 включает исправление для этой проблемы:
— добавлена ​​директива max_file_uploads INI, которая может быть установлена ​​для ограничения количества загрузок файлов на запрос до 20 по умолчанию, чтобы предотвратить возможный DOS из-за временного исчерпания файлов.
3. Установите расширение Suhosin PHP
Расширение Suhosin PHP имеет параметр с именем suhosin.upload.max_uploads . Этот параметр определяет максимальное количество файлов, которые могут быть загружены одним запросом, и по умолчанию установлено значение 25. Расширение Suhosin PHP не следует путать с Suhosin Patch, который не защищает от этой атаки.

Ссылки

Связанные уязвимости

Серьезность

Середина

Классификация

CVE-2009-4017 КВЕ-400 CVSS:3.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *