Является ли GET или POST более безопасным, чем другой? - PullRequest
272 голосов
/ 13 октября 2008

При сравнении HTTP GET с HTTP POST, каковы различия с точки зрения безопасности? Является ли один из вариантов более безопасным, чем другой? Если так, то почему?

Я понимаю, что POST не предоставляет информацию об URL, но есть ли в этом какая-то реальная ценность или это просто безопасность через неизвестность? Есть ли причина, по которой я предпочитаю POST, когда безопасность важна?

Edit:
По протоколу HTTPS данные POST кодируются, но могут ли сторонние пользователи прослушивать URL-адреса? Кроме того, я имею дело с JSP; При использовании JSP или аналогичной среды было бы справедливо сказать, что лучше всего избегать помещения конфиденциальных данных в POST или GET вообще и использовать вместо этого код на стороне сервера для обработки конфиденциальной информации?

Ответы [ 26 ]

417 голосов
/ 16 ноября 2009

Запрос GET незначительно менее защищен, чем запрос POST. Ни один не предлагает истинную «безопасность» сам по себе; использование POST-запросов не сможет магически обезопасить ваш сайт от злонамеренных атак на заметную сумму. Тем не менее, использование запросов GET может сделать безопасным приложение в противном случае.

Мантра о том, что вы «не должны использовать GET-запросы для внесения изменений», все еще очень верна, но это не имеет ничего общего с вредоносным поведением. Формы входа наиболее чувствительны к отправке с использованием неправильного типа запроса.

Поиск пауков и веб-ускорителей

Это реальная причина, по которой вам следует использовать POST-запросы для изменения данных. Поисковые пауки будут переходить по каждой ссылке на вашем сайте, но не будут отправлять найденные ими случайные формы.

Веб-ускорители хуже, чем поисковые пауки, потому что они работают на компьютере клиента и «щелкают» по всем ссылкам в контексте зарегистрированного пользователя . Таким образом, приложение, использующее запрос GET для удаления содержимого, даже если для этого требуется администратор, с радостью выполнит приказы (не вредоносного!) Веб-ускорителя и удалит все, что увидит .

спутанная атака депутата

A запутанная атака депутата (где заместитель - браузер) возможна независимо от того, используете ли вы запрос GET или POST .

На веб-сайтах, контролируемых злоумышленниками, GET и POST одинаково просты для отправки 1030 * без взаимодействия с пользователем .

Единственный сценарий, в котором POST немного менее восприимчив, заключается в том, что многие веб-сайты, которые не находятся под контролем злоумышленника (например, сторонний форум), позволяют встраивать произвольные изображения (позволяя злоумышленнику вводить произвольный запрос GET), но запретите все способы введения произвольного запроса POST, будь то автоматический или ручной.

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

Журналы прокси

Прокси-серверы, скорее всего, будут регистрировать GET URL полностью, без удаления строки запроса. Параметры запроса POST обычно не регистрируются. Куки вряд ли будут зарегистрированы в любом случае. (пример)

Это очень слабый аргумент в пользу POST. Во-первых, незашифрованный трафик может быть зарегистрирован полностью; у вредоносного прокси уже есть все, что нужно. Во-вторых, параметры запроса имеют ограниченное применение для злоумышленника: что им действительно нужно, так это файлы cookie, поэтому, если у них есть только логи прокси, они вряд ли смогут атаковать либо GET, либо POST URL.

Существует одно исключение для запросов на вход в систему: они, как правило, содержат пароль пользователя. Сохранение этого в журнале прокси открывает вектор атаки, который отсутствует в случае POST. Однако вход по обычному HTTP в любом случае небезопасен.

Кэш прокси

Кэширующие прокси могут сохранять ответы GET, но не ответы POST. Тем не менее, ответы GET можно сделать не кэшируемыми с меньшими усилиями, чем преобразование URL-адреса в обработчик POST.

HTTP "Referer"

Если пользователь должен был перейти на сторонний веб-сайт со страницы, обслуживаемой в ответ на запрос GET, этот сторонний веб-сайт получает доступ ко всем параметрам запроса GET.

Относится к категории «показывает параметры запроса третьей стороне», чья серьезность зависит от того, что присутствует в этих параметрах. POST-запросы, естественно, защищены от этого, однако для использования GET-запроса хакеру потребуется вставить ссылку на свой веб-сайт в ответ сервера.

История браузера

Этоочень похоже на аргумент «proxy logs»: запросы GET хранятся в истории браузера вместе с их параметрами. Атакующий может легко получить их, если у них есть физический доступ к машине.

Действие обновления браузера

Браузер будет повторять запрос GET, как только пользователь нажмет кнопку «обновить». Это может быть сделано при восстановлении вкладок после завершения работы. Таким образом, любое действие (скажем, платеж) будет повторяться без предупреждения.

Браузер не будет повторять запрос POST без предупреждения.

Это хорошая причина использовать только POST-запросы для изменения данных, но не имеет ничего общего со злонамеренным поведением и, следовательно, с безопасностью.

Так что мне делать?

  • Используйте только POST-запросы для изменения данных, в основном по причинам, не связанным с безопасностью.
  • Использовать только POST-запросы для форм входа в систему; в противном случае вводятся векторы атаки.
  • Если ваш сайт выполняет конфиденциальные операции, вам действительно нужен кто-то, кто знает, что они делают, потому что это не может быть рассмотрено в одном ответе. Вам нужно использовать HTTPS, HSTS, CSP, уменьшить внедрение SQL, внедрение сценария (XSS) , CSRF и множество других вещей, которые могут быть характерны для вашей платформы (например, Уязвимость массового назначения в различных средах: ASP.NET MVC , Ruby on Rails и т. д.). Нет единой вещи, которая будет отличать «безопасный» (не эксплуатируемый) и «не безопасный».

По протоколу HTTPS данные POST кодируются, но могут ли URL-адреса быть прослушаны третьей стороной?

Нет, их нельзя понюхать. Но URL-адреса будут храниться в истории браузера.

Было бы справедливо сказать, что лучшая практика состоит в том, чтобы избегать возможного помещения конфиденциальных данных в POST или GET вообще и использования кода на стороне сервера для обработки конфиденциальной информации вместо этого?

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

199 голосов
/ 13 октября 2008

Что касается безопасности, они по своей сути одинаковы. Хотя это правда, что POST не предоставляет информацию через URL-адрес, он предоставляет столько же информации, сколько GET в реальном сетевом взаимодействии между клиентом и сервером. Если вам нужно передать конфиденциальную информацию, вашей первой защитой будет передача по безопасному HTTP.

GET или сообщения строки запроса действительно хороши для информации, необходимой либо для закладки определенного элемента, либо для помощи в поисковой оптимизации и индексации элементов.

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

170 голосов
/ 18 января 2011

У вас нет большей защиты, потому что переменные отправляются через HTTP POST, чем переменные, отправляемые через HTTP GET.

HTTP / 1.1 предоставляет нам множество методов для отправки запроса :

  • OPTIONS
  • GET
  • ГОЛОВА
  • POST
  • PUT
  • DELETE
  • TRACE
  • CONNECT

Предположим, у вас есть следующий HTML-документ, использующий GET:

<html>
<body>
<form action="http://example.com" method="get">
    User: <input type="text" name="username" /><br/>
    Password: <input type="password" name="password" /><br/>
    <input type="hidden" name="extra" value="lolcatz" />
    <input type="submit"/>
</form>
</body>
</html>

Что спрашивает ваш браузер? Он спрашивает это:

 GET /?username=swordfish&password=hunter2&extra=lolcatz HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Теперь давайте представим, что мы изменили этот метод запроса на POST:

 POST / HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Content-Length: 49
 Cache-Control: max-age=0
 Origin: null
 Content-Type: application/x-www-form-urlencoded
 Accept: application/xml,application/xhtml+xml,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

 username=swordfish&password=hunter2&extra=lolcatz

ОБА из этих HTTP-запросов:

  • Не зашифрован
  • Включено в оба примера
  • Может быть переброшен и подвергаться атакам MITM.
  • Легко воспроизводится сторонними и скриптовыми ботами.

Многие браузеры не поддерживают методы HTTP, кроме POST / GET.

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

Итак, чтобы быть конкретным:

Один по своей природе более безопасен, чем другой? Я понимаю, что POST не раскрывает информацию об URL, но есть ли в этом реальная ценность или это просто безопасность через неизвестность? Какова лучшая практика здесь?

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

По протоколу https данные POST кодируются, но может ли URL-адрес быть прослушан третьей стороной?

Вот как работает SSL. Помните те два запроса, которые я отправил выше? Вот как они выглядят в SSL: (Я изменил страницу на https://encrypted.google.com/, так как example.com не отвечает по SSL).

POST через SSL

q5XQP%RWCd2u#o/T9oiOyR2_YO?yo/3#tR_G7 2_RO8w?FoaObi)
oXpB_y?oO4q?`2o?O4G5D12Aovo?C@?/P/oOEQC5v?vai /%0Odo
QVw#6eoGXBF_o?/u0_F!_1a0A?Q b%TFyS@Or1SR/O/o/_@5o&_o
9q1/?q$7yOAXOD5sc$H`BECo1w/`4?)f!%geOOF/!/#Of_f&AEI#
yvv/wu_b5?/o d9O?VOVOFHwRO/pO/OSv_/8/9o6b0FGOH61O?ti
/i7b?!_o8u%RS/Doai%/Be/d4$0sv_%YD2_/EOAO/C?vv/%X!T?R
_o_2yoBP)orw7H_yQsXOhoVUo49itare#cA?/c)I7R?YCsg ??c'
(_!(0u)o4eIis/S8Oo8_BDueC?1uUO%ooOI_o8WaoO/ x?B?oO@&
Pw?os9Od!c?/$3bWWeIrd_?( `P_C?7_g5O(ob(go?&/ooRxR'u/
T/yO3dS&??hIOB/?/OI?$oH2_?c_?OsD//0/_s%r

GET over SSL

rV/O8ow1pc`?058/8OS_Qy/$7oSsU'qoo#vCbOO`vt?yFo_?EYif)
43`I/WOP_8oH0%3OqP_h/cBO&24?'?o_4`scooPSOVWYSV?H?pV!i
?78cU!_b5h'/b2coWD?/43Tu?153pI/9?R8!_Od"(//O_a#t8x?__
bb3D?05Dh/PrS6_/&5p@V f $)/xvxfgO'q@y&e&S0rB3D/Y_/fO?
_'woRbOV?_!yxSOdwo1G1?8d_p?4fo81VS3sAOvO/Db/br)f4fOxt
_Qs3EO/?2O/TOo_8p82FOt/hO?X_P3o"OVQO_?Ww_dr"'DxHwo//P
oEfGtt/_o)5RgoGqui&AXEq/oXv&//?%/6_?/x_OTgOEE%v (u(?/
t7DX1O8oD?fVObiooi'8)so?o??`o"FyVOByY_ Supo? /'i?Oi"4
tr'9/o_7too7q?c2Pv

(примечание: я преобразовал HEX в ASCII, некоторые из них, очевидно, не должны отображаться)

Весь HTTP-разговор зашифрован, единственная видимая часть связи находится на уровне TCP / IP (имеется в виду IP-адрес и информация о порте подключения).

Итак, позвольте мне сделать здесь большое смелое заявление. Ваш веб-сайт не обеспечен большей безопасностью одного HTTP-метода, чем другой, хакеры и новички по всему миру точно знают, как делать то, что я только что продемонстрировал здесь. Если вы хотите безопасность, используйте SSL. Браузеры, как правило, хранят историю, в RFC2616 9.1.1 рекомендуется НЕ использовать GET для выполнения действий, но полагать, что POST обеспечивает безопасность, совершенно неверно.

Единственное, что POST - это мера безопасности? Защита от вашего ревнивого пролистывания истории вашего браузера. Вот и все. Остальной мир вошел в ваш аккаунт, смеясь над вами.

Чтобы дополнительно продемонстрировать, почему POST не является безопасным, Facebook использует POST-запросы повсеместно, так как может существовать такое программное обеспечение, как FireSheep ?

Обратите внимание, что вы можете быть атакованы CSRF , даже если вы используете HTTPS и ваш сайт не содержит XSS уязвимостей. Короче говоря, этот сценарий атаки предполагает, что жертва (пользователь вашего сайта или службы) уже вошла в систему и имеет надлежащий файл cookie, а затем браузер жертвы должен сделать что-то с вашим (предположительно безопасным) сайтом. Если у вас нет защиты от CSRF, злоумышленник может выполнить действия с учетными данными жертвы. Злоумышленник не может увидеть ответ сервера, поскольку он будет передан в браузер жертвы, но в этот момент ущерб обычно уже нанесен.

32 голосов
/ 13 октября 2008

Нет дополнительной защиты.

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

27 голосов
/ 13 октября 2008

Даже если POST не дает реального преимущества безопасности по сравнению с GET, для форм входа или любой другой формы с относительно конфиденциальной информацией убедитесь, что вы используете POST как:

  1. Информация POST ed не будет сохранена в истории пользователя.
  2. Конфиденциальная информация (пароль и т. Д.), Отправляемая в форме, не будет видна позже в строке URL (при использовании GET она будет отображаться в истории и строке URL).

Кроме того, GET имеет теоретический предел данных. POST нет.

Для реальной конфиденциальной информации обязательно используйте SSL (HTTPS)

18 голосов
/ 13 октября 2008

Ни один из GET и POST по своей природе не «более безопасен», чем другой, точно так же, как ни один из факсов и телефонов не «более безопасен», чем другой. Предоставляются различные методы HTTP, так что вы можете выбрать тот, который наиболее подходит для решения проблемы, которую вы пытаетесь решить. GET больше подходит для идемпотентных запросов, в то время как POST больше подходит для запросов "действий", но вы можете так же легко застрять в любом из них, если не понимаете архитектуру безопасности для приложение, которое вы поддерживаете.

Вероятно, было бы лучше, если бы вы прочитали Глава 9: Определения методов из HTTP / 1.1 RFC , чтобы получить общее представление о том, что GET и POST первоначально предполагалось, что они означают.

15 голосов
/ 14 октября 2008

Разницу между GET и POST следует рассматривать не с точки зрения безопасности, а с точки зрения их намерений по отношению к серверу. GET никогда не должен изменять данные на сервере - по крайней мере, не в журналах - но POST может создавать новые ресурсы.

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

Как упоминалось во многих ответах, единственная надежная ставка - через SSL.

Но убедитесь, что методы GET не фиксируют никаких изменений, таких как удаление строк базы данных и т. Д.

6 голосов
/ 14 октября 2008

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

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

Однако, просто отправка этих данных не делает их безопасными. Для этого вы хотите SSL. И GET, и POST отправляют данные в виде открытого текста по проводам при использовании по HTTP.

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

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

6 голосов
/ 13 октября 2008

Это не связано с безопасностью, но ... браузеры не кэшируют POST-запросы .

6 голосов
/ 13 октября 2008

Моя обычная методология выбора выглядит примерно так:

  • GET для элементов, которые будут извлечены позже по URL
    • например. Поиск должен быть GET, чтобы вы могли выполнить search.php? S = XXX позже
  • POST для пунктов, которые будут отправлены
    • Это относительно невидимое, сопоставленное с GET, и его сложнее отправить, но данные все еще можно отправить через cURL.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...