POST запрос, составное содержимое (multipart/form-data)
В жизни любого программиста попадаются задачки, которые человека цепляют. Вот не нравится стандартный метод решения и все! А порой бывает, что стандартные решения не подходят по какой-то причине. Некоторые люди обходят такие задачи стороной, другие же любят решать их. Можно даже сказать сами их находят. Одна из таких задач отсылка файла или несколько файлов методом POST.
Некоторые наверное скажут, эта задача совсем не задача. Ведь есть замечательная библиотека CURL, которая довольно простая и решает эту задачу легко! Но не спешите. Да, CURL мощная библиотека, да она загружает файлы, но… Как Вы знаете у нее есть маленькая особенность — файл должен быть размещен на жестком диске!
А теперь давайте представим себе такую ситуацию, Вы генерируете динамически файл или же он уже находится в памяти и нужно его отправить методом POST на удаленный Web сервер. Что же тогда получается? Перед его отправкой нужно его сохранить? Да именно так и поступило бы 90% программистов. Зачем искать лишние проблемы, если решение лежит на поверхности? Но мы же с Вами не из этих 90%! Мы же лучше, мы же можем решить любую задачку. Зачем нам лишнее действие? Во-первых, оно задействует не быструю файловую систему жесткого диска. Во-вторых, у нас может и не быть доступа к файловой системе или же там выделено слишком мало места.
Как же нам тогда решить эту задачку? Для этого надо взглянуть как собственно передаются данные методом POST. Единственный вариант решения — это передача файла составным запросом с помощью multipart/form-data. Этот метод хорошо описан в RFC7578. Давайте взглянем как будет выглядеть тело POST запроса multipart/form-data:
Наше тело состоит из двух частей, в первой части мы передаем значение поля формы name=«field» равное: text. Во второй части мы передаем поле name=«file» с содержимым файла filename=«sample.txt»: Content file. В заголовке мы указываем формат содержимого POST запроса — Content-Type: multipart/form-data, строку разделитель составных частей: boundary=————-573cf973d5228 и длину сообщения — Content-Length: 288.
Осталось, собственно, написать программу реализующий этот метод. Так как мы люди умные и не пишем по сто раз одно и тоже в разных проектах, то оформим все в виде класса реализующий этот метод. Плюс к этому, расширим его для разных вариантов отправки как файлов, так и простых элементов формы. А что бы отличить среди массива POST данных, наличие файла, создадим отдельный файл — контейнер с содержимым файла и его данных (имя и расширение). Таким образом он будет выглядеть следующим образом:
Теперь собственно сам класс по формированию тела multipart/form-data для POST запроса:
Данный класс состоит из нескольких методов. Метод — PartPost формирует отдельные части составного запроса, а метод — Get объединяет эти части и формирует тело POST запроса в формате — multipart/form-data.
Теперь у нас есть универсальный класс для отправки тела POST запроса. Осталось написать программу использующую данный класс для отправки файлов на удаленный Web сервер. Воспользуемся библиотекой CURL:
Если CURL не подходит, то данную библиотеку можно применить и для отправки через сокеты. Ну и собственно ссылки на источники:
What does enctype='multipart/form-data' mean?
What does enctype=’multipart/form-data’ mean in an HTML form and when should we use it?
![]()
9 Answers 9
When you make a POST request, you have to encode the data that forms the body of the request in some way.
- application/x-www-form-urlencoded (the default)
- multipart/form-data
- text/plain
Work was being done on adding application/json , but that has been abandoned.
(Other encodings are possible with HTTP requests generated using other means than an HTML form submission. JSON is a common format for use with web services and some still use SOAP.)
The specifics of the formats don’t matter to most developers. The important points are:
- Never use text/plain .
When you are writing client-side code:
- use multipart/form-data when your form includes any <input type="file"> elements
- otherwise you can use multipart/form-data or application/x-www-form-urlencoded but application/x-www-form-urlencoded will be more efficient
When you are writing server-side code:
- Use a prewritten form handling library
Most (such as Perl’s CGI->param or the one exposed by PHP’s $_POST superglobal) will take care of the differences for you. Don’t bother trying to parse the raw input received by the server.
Sometimes you will find a library that can’t handle both formats. Node.js’s most popular library for handling form data is body-parser which cannot handle multipart requests (but has documentation that recommends some alternatives which can).
If you are writing (or debugging) a library for parsing or generating the raw data, then you need to start worrying about the format. You might also want to know about it for interest’s sake.
application/x-www-form-urlencoded is more or less the same as a query string on the end of the URL.
multipart/form-data is significantly more complicated but it allows entire files to be included in the data. An example of the result can be found in the HTML 4 specification.
text/plain is introduced by HTML 5 and is useful only for debugging — from the spec: They are not reliably interpretable by computer — and I’d argue that the others combined with tools (like the Network Panel in the developer tools of most browsers) are better for that).
![]()
Quentin’s answer is right: use multipart/form-data if the form contains a file upload, and application/x-www-form-urlencoded otherwise, which is the default if you omit enctype .
- add some more HTML5 references
- explain why he is right with a form submit example
HTML5 references
There are three possibilities for enctype :
How to generate the examples
Once you see an example of each method, it becomes obvious how they work, and when you should use each one.
You can produce examples using:
- nc -l or an ECHO server: HTTP test server accepting GET/POST requests
- a user agent like a browser or cURL
Save the form to a minimal .html file:
We set the default text value to aωb , which means aωb because ω is U+03C9 , which are the bytes 61 CF 89 62 in UTF-8.
Create files to upload:
Run our little echo server:
Open the HTML on your browser, select the files and click on submit and check the terminal.
nc prints the request received.
Tested on: Ubuntu 14.04.3, nc BSD 1.105, Firefox 40.
multipart/form-data
For the binary file and text field, the bytes 61 CF 89 62 ( aωb in UTF-8) are sent literally. You could verify that with nc -l localhost 8000 | hd , which says that the bytes:
were sent ( 61 == ‘a’ and 62 == ‘b’).
Therefore it is clear that:
Content-Type: multipart/form-data; boundary=—————————735323031399963166993862150 sets the content type to multipart/form-data and says that the fields are separated by the given boundary string.
But note that the:
has two less dashes — than the actual barrier
This is because the standard requires the boundary to start with two dashes — . The other dashes appear to be just how Firefox chose to implement the arbitrary boundary. RFC 7578 clearly mentions that those two leading dashes — are required:
4.1. "Boundary" Parameter of multipart/form-data
As with other multipart types, the parts are delimited with a boundary delimiter, constructed using CRLF, "—", and the value of the "boundary" parameter.
every field gets some sub headers before its data: Content-Disposition: form-data; , the field name , the filename , followed by the data.
The server reads the data until the next boundary string. The browser must choose a boundary that will not appear in any of the fields, so this is why the boundary may vary between requests.
Because we have the unique boundary, no encoding of the data is necessary: binary data is sent as is.
TODO: what is the optimal boundary size ( log(N) I bet), and name / running time of the algorithm that finds it? Asked at: https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences
Content-Type is automatically determined by the browser.
application/x-www-form-urlencoded
Now change the enctype to application/x-www-form-urlencoded , reload the browser, and resubmit.
Clearly the file data was not sent, only the basenames. So this cannot be used for files.
As for the text field, we see that usual printable characters like a and b were sent in one byte, while non-printable ones like 0xCF and 0x89 took up 3 bytes each: %CF%89 !
Comparison
File uploads often contain lots of non-printable characters (e.g. images), while text forms almost never do.
From the examples we have seen that:
multipart/form-data : adds a few bytes of boundary overhead to the message, and must spend some time calculating it, but sends each byte in one byte.
application/x-www-form-urlencoded : has a single byte boundary per field ( & ), but adds a linear overhead factor of 3x for every non-printable character.
Therefore, even if we could send files with application/x-www-form-urlencoded , we wouldn’t want to, because it is so inefficient.
But for printable characters found in text fields, it does not matter and generates less overhead, so we just use it.
![]()
enctype=’multipart/form-data is an encoding type that allows files to be sent through a POST. Quite simply, without this encoding the files cannot be sent through POST.
If you want to allow a user to upload a file via a form, you must use this enctype.
When submitting a form, you tell your browser to send, via the HTTP protocol, a message on the network, properly enveloped in a TCP/IP protocol message structure. An HTML page has a way to send data to the server: by using <form> s.
When a form is submitted, an HTTP Request is created and sent to the server, the message will contain the field names in the form and the values filled in by the user. This transmission can happen with POST or GET HTTP methods.
-
tells your browser to build an HTTP message and put all content in the body of the message (a very useful way of doing things, more safe and also flexible). will submit the form data in the querystring. It has some constraints about data representation and length.
Stating how to send your form to the server
Attribute enctype has sense only when using POST method. When specified, it instructs the browser to send the form by encoding its content in a specific way. From MDN — Form enctype:
When the value of the method attribute is post, enctype is the MIME type of content that is used to submit the form to the server.
- application/x-www-form-urlencoded : This is the default. When the form is sent, all names and values are collected and URL Encoding is performed on the final string.
- multipart/form-data : Characters are NOT encoded. This is important when the form has a file upload control. You want to send the file binary and this ensures that bitstream is not altered.
- text/plain : Spaces get converted, but no more encoding is performed.
Security
When submitting forms, some security concerns can arise as stated in RFC 7578 Section 7: Multipart form data — Security considerations:
All form-processing software should treat user supplied form-data
with sensitivity, as it often contains confidential or personally
identifying information. There is widespread use of form "auto-fill" features in web browsers; these might be used to trick users to
unknowingly send confidential information when completing otherwise
innocuous tasks. multipart/form-data does not supply any features
for checking integrity, ensuring confidentiality, avoiding user
confusion, or other security features; those concerns must be
addressed by the form-filling and form-data-interpreting applications.Applications that receive forms and process them must be careful not to supply data back to the requesting form-processing site that was not intended to be sent.
It is important when interpreting the filename of the Content-
Disposition header field to not inadvertently overwrite files in the
recipient’s file space.
This concerns you if you are a developer and your server will process forms submitted by users which might end up containing sensitive information.
Отправка данных формы
В этой статье рассматривается, что происходит, когда пользователь отправляет форму — куда передаются данные и как мы их обрабатываем, когда они туда попадают? Мы также рассмотрим некоторые проблемы безопасности, связанные с отправкой данных формы.
| Предварительные знания: | Базовая компьютерная грамотность, понимание HTML и базовые знания по HTTP и программированию на стороне сервера. |
|---|---|
| Задача: | Понять, что происходит при отправке данных формы, в том числе получить представление о том, как данные обрабатываются на стороне сервера. |
Куда отправляются данные?
Здесь мы обсудим, что происходит с данными при отправке формы.
О клиентской/серверной архитектуре

WEB основан на очень простой клиент-серверной архитектуре, которую можно обобщить следующим образом: клиент (обычно веб-браузер) отправляет запрос на сервер (в основном веб-сервер, такой как Apache, Nginx, IIS, Tomcat, и т. д.), используя протокол HTTP. Сервер отвечает на запрос, используя тот же протокол.
На стороне клиента HTML-форма — это не более чем удобный способ настройки HTTP-запроса для отправки данных на сервер. Это позволяет пользователю предоставлять информацию для доставки в HTTP-запросе .
Примечание: Для получения более полного представления о том, как работают клиент-серверные архитектуры, ознакомьтесь с модулем «Первые шаги в программировании на стороне сервера».
На стороне клиента: определение способа отправки данных
Элемент <form> определяет способ отправки данных. Все его атрибуты предназначены для того, чтобы вы могли настроить запрос на отправку, когда пользователь нажимает кнопку отправки. Двумя наиболее важными атрибутами являются action и method .
Атрибут action
Этот атрибут определяет, куда отправляются данные. Его значение должно быть действительным URL. Если этот атрибут не указан, данные будут отправлены на URL-адрес страницы, содержащей форму.
В этом примере данные отправляются на абсолютный URL — http://foo.com :
Здесь мы используем относительный URL — данные отправляются на другой URL на сервере:
Если атрибуты не указаны, как показано ниже, данные из формы <form> отправляются на ту же страницу, на которой размещается данная форма:
Многие старые страницы используют следующий синтаксис, чтобы указать, что данные должны быть отправлены на ту же страницу, которая содержит форму; это было необходимо, потому что до появления HTML5 атрибут action был обязательным. Это больше не нужно.
Примечание: Можно указать URL, который использует протокол HTTPS (безопасный HTTP). Когда вы делаете это, данные шифруются вместе с остальной частью запроса, даже если сама форма размещается на небезопасной странице, доступ к которой осуществляется через HTTP. С другой стороны, если форма размещается на защищённой странице, но вы указываете небезопасный URL-адрес HTTP с атрибутом action , все браузеры выдают пользователю предупреждение о безопасности при каждой попытке отправки данных, поскольку данные не шифруются.
Атрибут method
Этот атрибут определяет способ отправки данных. Протокол HTTP предоставляет несколько способов выполнить запрос; Данные HTML-формы могут передаваться несколькими различными способами, наиболее распространёнными из которых являются метод GET и метод POST .
Чтобы понять разницу между этими двумя методами, давайте вернёмся назад и рассмотрим, как работает HTTP. Каждый раз, когда вы хотите получить доступ к ресурсу в Интернете, браузер отправляет запрос на URL-адрес. HTTP-запрос состоит из двух частей: заголовка, который содержит набор глобальных метаданных о возможностях браузера, и тела, которое может содержать информацию, необходимую серверу для обработки конкретного запроса.
Метод GET
Метод GET — это метод, используемый браузером, который говорит серверу, что нужно отправить назад данный ресурс: «Эй, сервер, я хочу получить этот ресурс». В этом случае браузер отправляет пустое тело. Поскольку тело пустое, если форма отправляется с использованием данного метода, данные, отправляемые на сервер, добавляются к URL-адресу.
Рассмотрим следующую форму:
Поскольку используется метод GET , вы увидите URL www.foo.com/?say=Hi&to=Mom , который появится в адресной строке браузера при отправке формы.
Данные добавляются в URL как последовательность пар имя / значение. После того, как URL веб-адрес закончился, мы добавляем знак вопроса ( ? ), за которым следуют пары имя / значение, каждая из которых разделена амперсандом ( & ). В этом случае мы передаём две части данных на сервер:
- say , со значением Hi
- to , со значением Mom
HTTP-запрос имеет следующий вид:
Примечание: вы можете найти этот пример на GitHub — смотрите get-method.html (see it live also).
Метод POST
Метод POST немного отличается. Браузер использует этот метод для связи с сервером при запросе ответа с учётом данных, представленные в теле HTTP-запроса: «Эй, сервер, взгляни на эти данные и отправь мне соответствующий результат». Если форма отправляется с использованием этого метода, данные добавляются в тело HTTP-запроса.
Давайте рассмотрим пример — это та же самая форма, которую мы рассматривали в разделе GET выше, но с атрибутом method , установленным в post .
Когда форма отправляется с использованием метода POST , данные добавляются не к URL-адресу, а включаются в тело запроса. HTTP-запрос имеет следующий вид:
Заголовок Content-Length указывает размер тела, а заголовок Content-Type указывает тип данных, отправляемых на сервер. Мы обсудим эти заголовки позже.
Примечание: вы можете найти этот пример на GitHub — смотрите post-method.html (see it live also).
Просмотр HTTP-запросов
HTTP-запросы никогда не отображаются пользователю (если вы хотите их видеть, вам нужно использовать такие инструменты, как Firefox Network Monitor или Chrome Developer Tools). Например, данные формы можно увидеть на вкладке Сеть (Network) в Chrome следующим образом (после отправки формы):
- Нажмите F12
- Выберите Network
- Выберите «All»
- Выберите «foo.com» во вкладке «Name»
- Выберите «Headers»
Затем вы можете получить данные формы, как показано на рисунке ниже.

Единственное, что отображается пользователю — вызываемый URL. Как упоминалось раннее, запрос с методом GET позволит пользователю увидеть информацию из запроса в URL, а запрос с методом POST не позволит. Две причины, почему это может быть важно:
- Если необходимо отправить пароль (или любую другую важную информацию), никогда не используйте метод GET , иначе рискуете отобразить эту информацию в URL-строке, что небезопасно.
- Если необходимо отправить большой объем информации, POST -метод является предпочтительным, так как некоторые браузеры ограничивают длину URL. К тому же, многие сервера так же ограничивают длину обрабатываемых URL.
На стороне сервера: получение данных
Какой бы HTTP вы не выбрали, сервер возвращает строку, которая будет последовательно проанализирована для получения данных в формате листа с парами ключ/значение. Способ получения доступа к этому листу зависит от платформы разработки или особенностей фреймворка, который вы можете использовать. Технологии, которые вы используете, определяют, как обрабатываются скопированные ключи. Часто, приоритетным является последнее полученное значение для данного ключа.
Пример: Чистый PHP
PHP предлагает несколько глобальных объектов для доступа к данным. Например, вы используете POST -метод, в приведённом ниже примере данные просто получаются и показываются пользователю. Разумеется, как использовать данные — решать только вам. Вы можете отобразить эти данные, поместить в базу данных, отправить по почте или передать эти данные куда-либо ещё.
Пример показывает страницу с данными, которые мы отправили. Вы можете посмотреть это в действии в нашем файле с примером: php-example.html — который содержит те же данные, которые вы видели раньше: method : post и action из php-example.php . Когда данные переданы на отправку (submit), они переданы в форму php-example.php, которая содержит PHP код из примера выше. Когда код будет выполнен, браузер выведет (output) обработанное сообщение: Hi Mom .

Примечание: Этот пример не будет работать, когда вы загружаете его в браузер локально — браузер не может интерпретировать PHP код, после отправки данных из формы, браузер просто предложит загрузить PHP файл. Чтобы пример заработал, необходимо отправить его на PHP сервер. Для тестирования PHP на локальных серверах можете пробовать MAMP (Mac and Windows) и/или AMPPS (Mac, Windows, Linux).
Пример: Python
Этот пример показывает, как вы можете использовать Python для решения той же задачи — отобразить отправленные данные на странице. В этом примере используется Flask framework для визуализации шаблонов, поддерживающих форму отправки данных (смотри python-example.py).
Два шаблона из коде выше взаимодействуют так:
-
: Та же форма, что и выше The POST method , только с использованием action к << url_for('hello') >> . (Это Jinja2 шаблон, который изначально HTML, но может содержать вызовы Python кода в фигурных скобках, которые запустятся веб-сервером. url_for(‘hello’) буквально говорит: после отправки данных переадресуй их в /hello .) : Этот шаблон просто содержит строку, которая отображает два бита данных, переданных ему при отображении. Это сделано с помощью функции hello() , указанной выше, которая выполняется, когда запрос направляется в /hello URL.
Примечание: Опять же, этот код не будет работать, если вы просто попробуете загрузить его прямо в браузер. Python работает немного иначе, чем PHP — чтобы запустить этот код, нужно установить Python/PIP, потом установить Flask используя команду: pip3 install flask . После этого, вы сможете запустить файл из примера, используя команду: python3 python-example.py , потом открыть localhost:5000 в своём браузере.
Другие языки и фреймворки
Существует множество других серверных технологий, которые вы можете использовать для работы с формами, включая языки Perl, Java, .Net, Ruby, и прочее. Выбирайте тот, который нравится больше. К тому же, использовать вышеупомянутые технологии непосредственно, без использования фреймворков, может быть сложно. Лучше использовать один из множества высококачественных фреймворков, таких как:
-
для Python (немного тяжеловеснее, чем Flask, но больше инструментов и опций) для Node.js для PHP для Ruby для Elixir
Стоит отметить, что использование фреймворков и работа с формами — это не всегда легко. Но это намного легче, чем пытаться написать аналогичную функциональность с нуля, и это определённо сэкономит время.
Примечание: Обучению фреймворкам и работе с серверами не входит в рамки этой статьи. Если хотите узнать больше, ссылки ниже помогут в этом.
Особый случай: отправка файлов
Отправка файлов с помощью форм HTML — это особый случай. Файлы — это бинарные данные или рассматриваются как таковые, в то время как все остальные — это текстовые данные. Поскольку HTTP — это текстовый протокол, есть особые требования для работы с бинарными данными.
Атрибут enctype
Этот атрибут позволяет конкретизировать значение в Content-Type HTTP заголовок, включённый в запрос, при генерировании отправки формы. Этот заголовок очень важен, потому что указывает серверу, какой тип данных отправляется. По умолчанию это: application/x-www-form-urlencoded . На человеческом это значит: «Это форма с данными, которые были закодированы в URL параметры.»
Если хотите отправить файл, нужно сделать следующие три шага:
- Указать method атрибут POST , поскольку содержимое файла, как и сам файл, не могут быть отображены в URL параметрах.
- Установить в enctype значение multipart/form-data , потому что данные будут разбиты на несколько частей: одна часть на файл (две части на два файла), и одна часть на текстовые данные (при условии, если форма содержит поле для получения тестовых данных).
- Подключите один или более File picker виджетов, чтобы позволить своим пользователям выбрать, какие и сколько файлов будут загружены.
Примечание: Некоторые браузеры поддерживают multiple атрибут элемента <input> , который позволяет выбрать больше одного файла для загрузки, при использовании одного элемента <input> . То, как сервер работает с этими файлами, напрямую зависит от технологий, используемых на сервере. Как упоминалось ранее, использование фреймворков сделает вашу жизнь намного легче.
Предупреждение: Многие сервера имеют заданные ограничения на размер загружаемых файлов и запросы от пользователей, чтобы защититься от возможных злоупотреблений. Важно проверять эти ограничения у администратора сервера, прежде чем загружать файлы.
Проблемы безопасности
Каждый раз, когда вы отправляете данные на сервер, вы должны учитывать безопасность. HTML-формы являются наиболее распространёнными векторами атак на серверы(места, где могут происходить атаки). Проблемы вытекают не из самих форм HTML, а из-за того, как сервер обрабатывает данные из этих форм.
В зависимости от того, что вы делаете, вы можете столкнуться с некоторыми очень известными проблемами безопасности:
XSS «Межсайтовый скриптинг» и CSRF «Подделка межсайтовых запросов»
Межсайтовый скриптинг (XSS «Cross Site Request Forgery») и подделка межсайтовых запросов (CSRF «Cross-Site Scripting») — это распространённые типы атак, которые происходят при отображении данных после ответа сервера или другого пользователя.
Межсайтовый скриптинг (XSS «Cross Site Request Forgery») позволяет злоумышленникам внедрить клиентский скрипт в веб-страницы, просматриваемые другими пользователями. Подделка межсайтовых запросов (CSRF «Cross-Site Scripting») может использоваться злоумышленниками для обхода средств контроля доступа, таких как одна и та же политика происхождения. Последствие от этих атак может варьироваться от мелких неудобств до значительного риска безопасности.
CSRF-атаки аналогичны XSS-атакам в том, что они начинаются одинаково — с внедрения клиентского скрипта в веб-страницы — но их конечные цели разные. Злоумышленники CSRF пытаются назначить права пользователям с более высоким уровнем прав доступа(например, администратору сайта), чтобы выполнить действие, которое они не должны выполнять (например, отправка данных ненадёжному пользователю). Атаки XSS используют доверие пользователя к веб-сайту, в то время как атаки CSRF используют доверие веб-сайта к пользователю.
Чтобы предотвратить эти атаки, вы всегда должны проверять данные, которые пользователь отправляет на ваш сервер, и (если вам нужно отобразить их) стараться не отображать HTML-контент, предоставленный пользователем. Вместо этого вы должны обработать предоставленные пользователем данные, чтобы не отображать их слово в слово. Сегодня почти все платформы на рынке реализуют минимальный «фильтр», который удаляет элементы HTML <script> , <iframe> (en-US) и <object> (en-US) полученных от любого пользователя. Это помогает снизить риск, но не исключает его полностью.
SQL — вброс
SQL -вброс представляет собой тип атак, при которых осуществляется попытка выполнения действия с базой данных, используемой целевым веб-сайтом. В этих случаях обычно осуществляется отправка SQL-запроса в надежде, что сервер выполнит этот запрос (обычно при попытке сервера приложения сохранить данные, отправляемые пользователем). Данный вид атак является одним из самых направленных атак на веб-сайты.
Последствия могут быть ужасающими, начиная от потери данных и заканчивая утратой контроля над всей инфраструктурой веб-сайта за счёт повышения привилегий. Это очень серьёзная угроза, поэтому никогда не сохраняйте данные, отправляемые пользователем, без выполнения фильтрации данных (например, с помощью mysqli_real_escape_string() .
Вброс HTTP-заголовка и email
Эти виды атак могут проявляться, когда ваше приложение создаёт заголовки HTTP или электронные почтовые адреса на основании данных, введённых пользователем в форму. Такие атаки напрямую не повреждают сервер или пользователей, однако создают уязвимость для таких угроз, как перехват сессии, или для фишинговых атак.
Такие атаки являются самыми незаметными, но при этом могут превратить ваш сервер в зомби.
Будьте параноиком: никогда не доверяйте вашим пользователям
Как вы боретесь с такими угрозами? Этот вопрос выходит далеко за рамки данной статьи, но есть несколько общих правил, которые следует всегда соблюдать. Самое важное из них — никогда не доверяйте вашим пользователям, в том числе себе; даже проверенный пользователь может быть атакован.
Все данные, поступающие на ваш сервер, необходимо проверять и санитизировать. Все и всегда. Без исключений.
- Избегайте потенциально опасных символов. Конкретные символы, с которыми следует соблюдать осторожность, зависят от контекста, в котором используются данные, а также от используемой платформы. Однако, все языки на стороне сервера имеют соответствующие функции для обеспечения такой защиты.
- Ограничьте входящий объем данных для поступления только реально необходимых данных.
- Помещайте загруженные файлы в песочницу (храните их на другом сервере и предоставляйте доступ к файлам только через отдельный поддомен или даже через совершенно другое доменное имя).
Соблюдая эти три правила, вы сможете избежать многих/большинства проблем. При этом следует помнить, что периодически необходимо проводить анализ защищённости, желательно квалифицированной сторонней организацией. Не считайте, что вы уже сталкивались со всеми возможными угрозами.
Примечание: В статье Безопасность веб-сайта нашего раздела серверного обучения приведено подробное обсуждение упомянутых угроз и возможных способов их устранения.
Заключение
Как мы увидели, отправлять формы просто, однако защитить приложение может быть довольно трудно. Просто помните, что фронтенд разработчики не должны задавать модель безопасности для приложения. Да, как мы увидим далее, мы можем проверить данные на стороне клиента, однако сервер не может доверять этой проверке, потому что он никогда не может по-настоящему узнать что происходит на стороне клиента.
Смотрите также
Если вы хотите узнать больше об обеспечении безопасности веб-приложений, вы можете использовать следующие источники информации:
The HTTP is a protocol allowing you to fetch resources such as JSON data and HTML documents. Two sides of the connection, the client and the server, communicate by exchanging messages. The message sent by the client is a request. The message sent by the server is a response. When using Node.js, you can act like either one of them. In this article, we cover how to make requests.
This article presents the way to make HTTP requests in pure Node.js. Other viable solution is using a library like axios.
Node.js TypeScript: sending HTTP requests
To send a request, we need to use the http module. It contains the request method. Let’s try it out!
