Tuesday, July 5th, 2011 10:13 pm

Большинство веб-разработчиков знают Правило Правой Руки для HTTP: если запрос меняет состояние сервера, его надо отправлять методом POST, если не меняет — можно использовать GET.

Веб-форма при отправке на сервер меняла его состояние, поэтому разработчки совершенно справедливо указали method=”POST”.

Но если обработчик обнаружил ошибки, форму надо показать снова. И признак хорошего тона — не заставлять пользователя при этом вбивать всё заново, а подставить ранее введённые им значения и показать пальцем, в каких полях ошибки. Разработчики так и сделали. Но форму у них обрабатывает один скрипт, а показывает другой, поэтому при обнаружении ошибок возврат к странице с формой делается редиректом. А POST при этом, как известно, не работает, поэтому умные разработчики передают все введённые параметры GET’ом. Попросту говоря, прямо в URL’е.

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

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

В общем, ситуация типа “да вы здесь все молодцы…” ©.

P.S. Если кто случайно не знает прописных истин: надо либо использовать для показа формы и её обработки один и тот же скрипт (тогда редирект не понадобится), либо, если уж по каким-то причинам скриптов два, хранить параметры в сессии на сервере, а клиенту передавать только её идентификатор, да и тот лучше не в URL’е, а в куке.

Оригинал этой записи. Комментировать можно тут или там.

Любые материалы из этого блога запрещается использовать на сайте livejournal.ru в любой форме и любом объёме

Tuesday, July 5th, 2011 10:30 pm (UTC)
Помнится, если следовать букве PCI DSS, то полный некриптованный номер карты нельзя хранить даже в сессионных данных.
Tuesday, July 5th, 2011 10:56 pm (UTC)
АДъ.
скажи, что ты шутишь.
Wednesday, July 6th, 2011 12:13 am (UTC)
Hell is just around.

Увы, шутки в этом меньше, чем хотелось бы.
Wednesday, July 6th, 2011 12:32 am (UTC)
Это где такая радость? Чтоб за 300 верстЪ...
Wednesday, July 6th, 2011 06:25 am (UTC)
Не волнуйся, тебе это не грозит :)
Wednesday, July 6th, 2011 06:26 am (UTC)
Там можно и криптованный хранить
Wednesday, July 6th, 2011 06:27 am (UTC)
Увы, это суровая реальность. У меня бы фантазии не хватило такое выдумать.
Wednesday, July 6th, 2011 06:33 am (UTC)
Кстати, а эти правила где-нибудь публично доступны? Я бы с интересом почитал.
Wednesday, July 6th, 2011 06:47 am (UTC)
https://www.pcisecuritystandards.org/
Wednesday, July 6th, 2011 06:59 am (UTC)
PCI DSS v2.0 10/28/2010 PCI-DSS Agreement Required
Wednesday, July 6th, 2011 07:01 am (UTC)
тебе сложно нажать "принимаю"?
Wednesday, July 6th, 2011 07:06 am (UTC)
Да, что-то я отупел совсем
Wednesday, July 6th, 2011 07:14 am (UTC)
Давным давно читал историю, в которой рассказывалось как один из ранних веб-шопов передавал данные о цене товара на checkout в URL'e, не проводя никаких дополнительных проверок. Достаточно было немножко подкорректировать этот URL чтоб получить скидку любого размера :-).
Wednesday, July 6th, 2011 07:17 am (UTC)
полный некриптованный номер карты иногда написан полностью на чеке, который выдаётся при покупке и выбрасывается в ведро. вместе с именем владельца. жалко, что CVV там не пишут, а то бы на пивко хватило.
Wednesday, July 6th, 2011 07:18 am (UTC)
Да щаз.
На чеке либо 1234 XXXX XXXX 5678 либо ....5678.
Wednesday, July 6th, 2011 07:21 am (UTC)
Это всё херня.
Одна очень крупная компания принимала оплату следующим образом - процессинговый центр кроме всего прочего мог отвечать на мыло, прошла оплата или нет. Разработчики сайта создали ящик на mail.ru (вот те плюс!), сказали процессингу сваливать туда ответ, а потом скриптом выгребали. Соответственно, пользователь об этом ничего не знал.

Причём и компания, и разработчик сайта - довольно крупные и известные у нас в городе, обычно таким доверяют.
Wednesday, July 6th, 2011 07:24 am (UTC)
Да щаз.
Будучи в Петербурге нашёл билет в .... эээээ, чорт, забыл куда, в какую-то достопримечательность, к нему был приколот нестандартного размера чек, на котором было написано всё, кроме Expire date и CVV. Показал друзьям, они порадовались.
Wednesday, July 6th, 2011 07:32 am (UTC)
Это в теории. А на практике он там иногда действительно бывает полностью написан
Wednesday, July 6th, 2011 07:32 am (UTC)
Это клиника, и это не норма, а нарушение стандартов.
Я, правда, не в курсе, как за это взъ....ть.
Wednesday, July 6th, 2011 07:55 am (UTC)
наняли индусов за копейку?
Wednesday, July 6th, 2011 08:23 am (UTC)
Нажаловаться в платёжную систему на банк-эквайрер.
Wednesday, July 6th, 2011 08:39 am (UTC)
А это реально работает?
Wednesday, July 6th, 2011 08:55 am (UTC)
по-разному … помнится пытались визе вынести мозг, когда сити использовал пин для логина в веб-морду … получили отписки …

я, честно говоря, не помню чтобы в банкоматных чеках был полный номер у кого, там вроде есть жесткие требования, с посовскими терминалами кажись такого требования нет, ибо тоже пытались пинать то ли на тему перекрестка, то ли на тему живого еще тогда меркадо, что у них на чеках был полный номер карты — банк-экварер послал, виза тоже отписалась … хотя может и пнули их, ибо сейчас полного номера на чеках перекрестка вроде нет …
Wednesday, July 6th, 2011 08:56 am (UTC)
хе-х, после ситибанка, у которого можно было посмотреть чужие счета, просто поменяв id-ник в урле всё меркнет …
Wednesday, July 6th, 2011 09:35 am (UTC)
Когда как. Иногда работает.
Wednesday, July 6th, 2011 03:21 pm (UTC)
Это как раз был не банкоматный, а POS-чек, причём необычного вида, как не на ленте печатают, а на заранее заготовленных карточках.
Wednesday, July 6th, 2011 03:33 pm (UTC)
У нас тут таких местных индусов - хоть жопой ешь.

Лет цать назад нужно было поправить dns-записи у хостера. Никто у меня не спросил никаких документов, просто "я такой-то из компании такой-то, нам надо mx поправить".
[identity profile] andrey sherbinko (from livejournal.com)
Wednesday, July 20th, 2011 01:55 pm (UTC)
Лишние понты, какие-то, видимо автор считает себя крутым специалистом
При чём тут GET и POST проблема же не в этом

Во первых, сервер и так знает все эти данные, ибо именно ему передаются реквизиты карточки. Никаким проксям это не доступно, ведь используется HTTPS, верно?
Во вторых, печатание этих реквизитов в логах это logging issue. Что мешает сервер залогировать параметры переданные POST-ом? Если бы я был разработчиком и мне надо было выдать параметры запроса, мне было бы наплевать как они переданы GET-ом или POST-ом. В сервлетах, к примеру, они вообще не различаются.

Насчёт закладок - могут быть проблемы, конечно, но надо смотреть код.
Wednesday, July 20th, 2011 02:10 pm (UTC)
А если б вы были моим разработчиком, я бы вас с таким подходом к безопасности даже и на работу не взял.

Залоггировать параметры POST'а можно, конечно, но для этого надо совершать нетривиальные телодвижения. Параметры GET'а пишутся в лог по умолчанию.

Ну и на досуге попробуйте запомнить в закладках браузера ссылочку на форму, отправляемую на сервер POST'ом, _вместе со всеми параметрами этой формы_. Когда получится - возвращайтесь, поговорим дальше.
[identity profile] andrey sherbinko (from livejournal.com)
Wednesday, July 20th, 2011 02:27 pm (UTC)
Нетривиальные телодвижения? Вы наверное, шутите? Хотя я не знаю какой язык и фреймоворк вы используете. Об этом надо было написать, иначе получется какое-то обсуждение сферического коня в вакууме.
Чего стоит эта фраза "И, естественно, при последующей отправке формы весь этот набор оседает в логах веб-сервера в виде реферера". Для кого естественно? Почему естественно? Какого веб сервера? На моих серверах никакие урлы в логах не оседают.

При чём тут подход к безопасности? Пост был про GET vs POST. С точки зрения безопасности они не различаются.
Не понимаю к чему был вопрос про закладки. Я пару раз действительно делал закладку с GET-параметрами которые должны были передаваться постом, чисто для удобства. И что?
Да, есть особенности, но никак не связанные с "дырявостью" GET-а.
Wednesday, July 20th, 2011 02:39 pm (UTC)
Какое слово из фразы "оседает в логах веб-сервера" вызывает затруднения? Apache, наиболее распространённый из них. При чём тут вообще языки и фреймворки?

Если вы действительно до сих пор не понимаете, чем различаются GET и POST с точки зрения безопасности, флаг вам в руки, продолжайте передавать параметры GET'ом. И не жалуйтесь потом, когда к вам, по примеру Мегафона, придёт Яндекс или Гугл.

А насчёт закладок - как, например, сохранить в браузере ссылку на https://passport.yandex.ru/passport?mode=passport с именем _username_ и паролем _pass_?