Pull to refresh

Comments 101

Тем самым мы решим сразу две задачи – и защиту от CSRF и контроль целостности набора передаваемых параметров – пользователь уже не сможет «поиграться» с полями формы и попробовать добавить или убрать что-нибудь из параметров.

Какую именно задачу вы пытаетесь тут решить?

Теперь вы можете подписывать данные, передаваемые через HTTP/REST API

Подписывать-то можно, но как удостовериться, что данные пришли именно от ожидаемого отправителя? И чем это лучше банального HTTPS?
Какую именно задачу вы пытаетесь тут решить?

Задачу валидации входящих данных из Web-формы (убедиться что набор переданных полей соответствует изначальному набору формы и не изменен пользователем), а также защиту формы от CSRF.

Подписывать-то можно, но как удостовериться, что данные пришли именно от ожидаемого отправителя?

Если секретный ключ знают только отправитель и получатель данных — по подписи и удостовериться. Вокруг этого собственно все и крутится.

И чем это лучше банального HTTPS?

HTTPS шифрует данные, чтобы они не могли быть прочитаны. В случае если реализовать проверку сертификата клиента — то да, можно проверять отправителя — но это сложный способ и непрактичный, если например клиенты обращаются к API, скажем платежного шлюза и посылают запросы, целостность которых должна быть гарантирована.
Задачу валидации входящих данных из Web-формы (убедиться что набор переданных полей соответствует изначальному набору формы и не изменен пользователем)

А зачем вообще передавать эти данные через форму тогда, если пользователь не может их изменить?

также защиту формы от CSRF.

Каким образом?

Если секретный ключ знают только отправитель и получатель данных — по подписи и удостовериться.

Это если отправитель один. А если их много?
А зачем вообще передавать эти данные через форму тогда, если пользователь не может их изменить?

Мы говорим о наборе полей, а не самих данных. В форме есть набор полей — зачем пользователю менять сам набор, если он должен заполнить только значения?

Каким образом?

Читайте статью: «В частности, таким образом, можно формировать более продвинутые CSRF-токены для форм, используя в качестве секретного ключа какой-нибудь внутренний идентификатор, привязанный к сессии пользователя.» — привязываем «секрет» к сессии и получаем автоматически CSRF-токен.

Это если отправитель один. А если их много?

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

А еще гарантирует, что сообщение не было изменено в пути.

можно проверять отправителя — но это сложный способ

Чем он сложнее, чем HMAC, требующий pre-shared secret?

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

Что непрактичного в использовании HTTPS для гарантии целостности запросов?
HTTPS мы подразумеваем по-умолчанию. HMAC не ставится в противовес или замену HTTPS, а как дополнительный механизм аутентификации и проверки консистентности данных на логическом, а не на транспортном уровне. Улавливаете разницу?
Какой выигрыш вы получаете, используя HMAC в дополнение к HTTPS?
Защита логики в формах — раз.
Аутентификация и защита от изменения пользователем запросов в API, в частности, в платежных формах и платежных API — два.
Можете наглядно показать на примерах? Я вас не понимаю иначе.

А то ведь для аутентификации в API достаточно просто передать свой идентификатор, зачем HMAC-то поверх городить?
Есть сервер платежной системы, он принимает запросы на транзакции от клиентов, которых много. Передавая просто идентификтор — мы не можем клиента аутентифицировать. Это первый случай.

Второй случай — часто платежная форма инициализируется в виде GET или POST запроса, который происходит на стороне клиента (сабмитится форма в браузере) и в этом случае сервер получающей стороны должен быть уверен что данные сформированы легитимным клиентом и не были изменены. Так понятнее?
Передавая просто идентификтор — мы не можем клиента аутентифицировать.

Почему?

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

Данные сформированы легитимным клиентом — это та же самая аутентификация, см. выше.
Какие данные не были изменены и с какого момента?
Если клиент — это доверенная серверная часть и идентификатор такой, что его нельзя подобрать или угадать — то теоретически можно сделать так, как вы говорите. А если клиент — это форма в браузере пользователя, который может быть зловредным и изменит, скажем, сумму покупки, или идентификатор заказа, или еще какие-то данные, то без HMAC не обойтись и один лишь идентификатор передавать недостаточно.
Давайте мы не будем путать две разные вещи, а?

Еще раз, по порядку.

(1) в чем выигрыш от использования HMAC (по сравнению с (а) просто идентификатором (б) идентификатором и паролем (ц) идентификатором и хэшом от пароля + nonce) при аутентификации в API при работе поверх HTTPS?

(2) пожалуйста, опишите пошагово сценарий атаки, от которого вы пытаетесь защититься с помощью использования HMAC по форме (и сам способ защиты).
(1) Вы же сами дали ответ на свой вопрос в своём комментарии. В абзаце описании атаки с увеличением длины сообщения вы найдёте ответы, если рассматривать схемы построеные с применением классической схемы Меркла-Дамгарда, коим и является SHA-2.
А причем тут sha-2? Мой вопрос был про работу поверх https.
Вопрос начинался с
в чем выигрыш от использования HMAC (по сравнению ...


При тестировании веб-приложений в финансовом секторе (о котором не раз упоминал автор) предпалагается, что HTTPS соединение может быть прослушано. Далее ответ на ваш вопрос в предыдущем комментарии.
Эээ, кем предполагается?

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

Теми, кто тестирует эти системы. :)

… потому что в описываемых автором платежных сценариях по этому https дальше полетят данные моей кредитной карты.

Автор лишь описывает метод, позволяющий проверить целостность данных, а не их конфеденциальность. И его метод является более защищённым, с точки зрения криптографии, чем просто хэшифрование с секретным значением (и случайными данными). Но и у него есть свои недостатки.
Теми, кто тестирует эти системы.

Понимаете, в ряде контекстов такое предположение автоматически делает систему незащищенной (в частности, я тут разрабатываю маленький проектик, так вот там утечка пользовательских данных опасна сама по себе).

Автор лишь описывает метод, позволяющий проверить целостность данных, а не их конфеденциальность. И его метод является более защищённым, с точки зрения криптографии, чем просто хэшифрование с секретным значением (и случайными данными).

Вопрос в области применимости этого метода. Я вот представлю себе две (скорее всего, это не исключительно, но близко): обмен по незащищенным каналам (например, есть hawk, http-аутентификация на основе HMAC) и контроль полномочий третьей стороны без хранения состояния.

Я любопытства ради разверну второй пункт, просто ради демонстрации хода мысли. Условия: есть система А, это api, в нем есть аутентификация и список ресурсов, доступных после аутентификации. Есть система Б, которая относится к тому же решению, но частично физически отделена. Она отдает собственно тела ресурсов (Грубо говоря, Фейсбук-вебсайт и Фейсбук-CDN-с-картинками). Есть клиент (приложение или третий веб-сайт), который идет в api, получает список ресурсов, потом идет в хранилище и достает тела ресурсов на основании адресов, полученных из api. Права клиента со временем могут меняться (т.е., ранее доступный ему ресурс может быть отозван).

Решение (1): заставляем клиент так же аутентифицироваться в хранилище, потом проверяем доступность. Достоинства: самый безопасный подход. контроль доступа настолько полный, насколько это вообще может сделать api. Недостатки: у клиента усложняется процесс обмена (особенно если это браузер и картинки), увеличивается нагрузка на подсистему аутентификации и авторизации.

Решение (2): вместе с каждым адресом ресурса отдаем короткоживущий идентификатор, по нему хранилище проверяет права доступа. Достоинства: клиентский процесс радикально упрощается. Недостатки: идентификатор короткоживущий, а не одноразовый, поэтому отъем прав происходит не мгновенно (точнее, можно сделать мгновенно, но для этого в апи надо делать убийство идентификаторов, это будет очень дорого), и хранилищу все еще надо куда-то ходить, чтобы проверять валидность идентификаторов.

Решение (3): вместе с каждым адресом ресурса отдаем таймстамп + HMAC (от таймстампа), хранилище по HMAC проверяет, что таймстамп действительно пришел от api, и отсчитывает время жизни от него. Достоинства: клиентский процесс такой же простой, как в (2), но хранилищу теперь не надо никуда ходить, достаточно знать shared key. Недостатки: задержка при отъеме прав (причем теперь неустранимая, в отличие от (2)) и… а вроде бы и все. Да?
Оффтоп. Вы уже так много материала написали по поводу данной статьи, что можно все комментарии собрать и оформить в виде отдельной статьи со своим видением ситуации.

Про (2) («пожалуйста, опишите пошагово сценарий атаки...») я вообще ничего не писал — этот вопрос относится к автору. Я согласен, что чёткого описания модели угроз в статье нет. Но с другой стороны, это не научная статья, а лишь описание реализации одного из методов (на сколько я это вижу).

А вообще, автор рассматривает один из методов (причём не самый плохой) обеспечения целостности данных, а не универсальный методо защиты от всех существующих и потенциальных атак. Он ничего не упоминает об обеспечении конфеденциальности или неотказуемости (это к ЕЦП).
Вы уже так много материала написали по поводу данной статьи, что можно все комментарии собрать и оформить в виде отдельной статьи со своим видением ситуации.

Я не вижу, что я могу сказать нового аудитории — все мои знания так или иначе почерпнуты из литературы и интернетиков.

Про (2) («пожалуйста, опишите пошагово сценарий атаки...») я вообще ничего не писал — этот вопрос относится к автору. Я согласен, что чёткого описания модели угроз в статье нет. Но с другой стороны, это не научная статья, а лишь описание реализации одного из методов (на сколько я это вижу).

Я у вас, вроде, ничего про это и не спрашивал…

А вообще, автор рассматривает один из методов (причём не самый плохой) обеспечения целостности данных, а не универсальный методо защиты от всех существующих и потенциальных атак.

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

HTTPS сам по себе обеспечивает лишь конфиденциальность данных, иногда ещё и целостность, при передаче браузер<->сервер (или сервер<->сервер). Но о самих данных он ничего не знает (прсто байтики информации). Ему будет всё ровно «sum=10» или «sum=1000». Проверку целостности «sum» и пытается выполнить автор при помощи HMAC.

Или вы говорите про какие-то другие «соседние методы»?
HTTPS сам по себе обеспечивает лишь конфиденциальность данных, иногда ещё и целостность, при передаче браузер<->сервер (или сервер<->сервер). Но о самих данных он ничего не знает (прсто байтики информации). Ему будет всё ровно «sum=10» или «sum=1000».

Эээ, я всегда считал, что если у нас установлено https-соединение, то получающая сторона может быть уверена, что получает именно те данные, которые отправила передающая сторона. Я где-то не прав?

Или вы говорите про какие-то другие «соседние методы»?

Ну, например, можно целиком все сообщение подписывать ЭЦП, или вообще подписывать и шифровать.
Эээ, я всегда считал, что если у нас установлено https-соединение, то получающая сторона может быть уверена, что получает именно те данные, которые отправила передающая сторона. Я где-то не прав?

Нет, почему же, Вы правы. Давайте попробую объяснить немного по другому. Конфеденциальность и целостность данных может происходить на уровне браузера (установлено HTTPS соединение) и на уровне пользователя (сервер проверяет, что данные не были изменены до/после/во время HTTPS сессии). Если HTTPS какием-то образом скомпроментирован, то должен оставаться ещё один уровень безопасности.

Хотя даже я слукавил. Основная цель HTTPS — это проверка того, что вы общаетесь с нужным сервером/клиентом (для защиты от атаки человек посередине). А конфеденциальность и целостность это уже побочные услуги, так сказать в дополнение.

Если сделать предположение, что HTTPS отсутствует (или может быть выполнена атака), то общение с сервером всё ровно должно происходить в защищённом режиме. Или должно быть доказано, что при таких условия злоумышленнику понадобится больше времени для компроментации информации, чем время жизни самой информации.
Я уже говорил: я привык рассматривать ситуацию «HTTPS скомпроментирован» как автоматическую компроментацию всего приложения, потому что в моем случае конфиденциальность информации превыше всего.

Вы предлагаете мне строить второй уровень шифрования (именно шифрования) поверх HTTPS?
Бывает целый ряд задач, когда к доверенному серверу через HTTPS подключается множество недоверенных клиентов, и реализация не предусматривает возможность добавлять авторизацию по клиентским сертификатам. Далеко не ходить за примером — API почти всех платежных систем используют HMAC в том или ином виде.
(Пойдем по кругу?)

Во-первых, я говорю про конфиденциальность данных, а вы — про авторизацию. Это разные вещи, и путать их не стоит.

Во-вторых, есть два разных сценария — мы рассматриваем компроментацию HTTPS, и мы ее не рассматриваем. Если мы ее рассматриваем, то не понятно, зачем там HTTPS изначально, и можно возвращаться к обсуждению «зачем HMAC используется в несекьюрных транспортах». Если мы ее не рассматриваем, то не понятно, какой выигрыш от использования HMAC (и эти сценарии мы уже обсуждали).

Вы предлагаете мне строить второй уровень шифрования (именно шифрования) поверх HTTPS?

В критичных приложениях, где без этого не обойтись, — да. В некритичных применять хотя бы целостность сообщений.

«HTTPS скомпроментирован» как автоматическую компроментацию всего приложения

А вы не сталкивались с больших компаниями, у которых есть свои ЦС, и которые фильтруют любой трафик, включая HTTPS (и это прописано в политике ИБ)?
В критичных приложениях, где без этого не обойтись, — да. В некритичных применять хотя бы целостность сообщений.

Я говорю про свой конкретный сценарий. Если у меня нарушена конфиденциальность — я могу накрываться полотенчиком и ползти на кладбище. Поэтому мне нет смысла строить дополнительный контроль целостности сообщений поверх HTTPS.

А вы не сталкивались с больших компаниями, у которых есть свои ЦС, и которые фильтруют любой трафик, включая HTTPS (и это прописано в политике ИБ)?

Сталкивался. Поскольку приложение, над которым я работаю, ориентировано на конкретных конечных пользователей (физиков), никто не ожидает, что они будут его использовать изнутри такой компании. Если же они это делают с компьютера, за которым у них нет контроля, они делают это на свой страх и риск. Дело в том, что внутри такой компании обычно не только есть фильтрация трафика, но и доменный контроль за компьютерами, а в этом случае защитить пользователя очень сложно (хотя и возможно).
Я говорю про свой конкретный сценарий.

Я всё же настаиваю, чтобы вы описали Ваш конкретный сценарий в отдельной статье, и объяснили почему проверка целостности данных, при помощи HMAC, лишняя и не имеет смысла.

Конкретно в сфере финансов — такой подход оправдан.
Потому что в моем конкретном сценарии при потере конфиденциальности данных все гарантии сервиса по отношению к пользователю нарушены, и сервис считается неработающим. Это такие входные условия.
Ну тогда вы уже ответили на вопрос в своём комментарии. Всё зависит от того где и как использовать, и от входных данных конечно же.
Вот мне и интересен круг задач, в которых HMAC применим. Я свои два примера, где я считаю его оправданным, привел.
Пример сценария с которым я сталкивался в реальной жизни. Есть мобильное устройство, на котором установлено приложение для оказания финансовых услуг. Предполагается, что первая инициализация приложения происходила через доверенную сеть пользователя, в результате которой сгенерирован секретный ключ на стороне клиента и сервера. Доступ к этим ключам получить не представляется возможным. Доступ к самому приложению не возможен из-за пароля, выбранного пользователем, и блокируется после нескольких попыток ввода неправильного пароля. Предполагается, что приложение переодически пересылает 1 цент на фиксированный счёт. Незащищенный паролем мобильный телефон был украден.

Цель злоумышленника перевести деньги на свой счёт и/или изменить количество переводимых денег.

Сценарий атаки без HMAC. Устанавливаем один из прокси-серверов с возможностью MitM, например mitmproxy или OWASP ZAP. Устанавливаем корневой сертификат на телефон. Далее перехватываем запрос, изменяем его. Profit.

Сценарий атаки c HMAC.
Проделывает тоже самое, что и в предыдущем пункте. Только теперь, для того, чтобы изменит сообщение нужно подделать и HMAC, среди данных передаваемого запроса к серверу содержится метка времени. Любая рассинхронизация с сервером более чем на 1 минуту приводит к автоматическому отфильтровыванию сообщения. Хэш (HMAC) берётся от всех полей заголовка http запроса и данных.
В этом сценарии, конечно, есть уйма сомнительных мест (самое дикое из которых — отсутствие certificate pinning), но я вас услышал.
Ну, например, можно целиком все сообщение подписывать ЭЦП, или вообще подписывать и шифровать.

В теории действительно более безопасней. А вы пробовали это реализовать на практике? Основная проблема будет в управлении ключами. Необходимо будет создавать и сопроваждать инфраструктуру открытых ключей. У какждого метода есть свои плюсы и минусы. Тот же SRP может быть использован, в некоторых случаях, в качестве замены на мобильных устройствах.
В теории действительно более безопасней. А вы пробовали это реализовать на практике?

К сожалению, да.

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

По вашему, сопровождать shared secret keys чем-то легче?
По вашему, сопровождать shared secret keys чем-то легче?

При симметричной криптографии всё можно засунуть в один сервер. А при безопасной реализайии ИВК, нужно отдельная инфраструктура со своими требованиями. Это не просто взяли сгенерировали кучу самоподписанных сертификатов и раздали их доверенным пользователям.
Это не просто взяли сгенерировали кучу самоподписанных сертификатов и раздали их доверенным пользователям.

Почему? Это же зависит от конкретной задачи.
Так не надо сумму покупки на клиенте считать и всё) Делайте как все белые люди корзину от клиента максимум ИД товара и его количество. А то что вы предлагаете не имеет смысла в случае с формой т.к. вы браузеру сначала отдаёте функцию шифрования и всё ваша защита становится вашей уязвимостью…
Ну хорошо :)))

По пункту номер 1:
а) сбрутили идентификатор — начали гнать запросы.
б и ц) будет работать, и будет достаточно секурно, если это сервер->сервер API взаимодействие.

По пункту номер 2:

Сценарий атаки:
Есть интернет-магазин «Ромашка» и банк «Рога и Копыта», который оказывает услуги интернет-эквайринга для Ромашки. На странице чекаута на сайте Ромашки есть форма с hidden-полями: merchant_id, order_id, amount, description. Форма сабмитится на URL банка. Лжепокупатель может изменить order_id или amount и оплатить совсем другой счет и более того — на другую сумму.

Способ защиты:
Передавать еще и HMAC, проверка которого на стороне сервера не даст пользователю изменить данные в форме.
сбрутили идентификатор

Сбрутить GUID? Вы серьезно? А что в этом случае мешает сбрутить секретный ключ для HMAC?

будет работать, и будет достаточно секурно, если это сервер->сервер API взаимодействие.

А если не сервер-сервер, то в чем отличие?

Более того, почему вы считаете, что «сбрутить идентфикатор» можно, а «сбрутить идентификатор и пароль» нельзя?

На странице чекаута на сайте Ромашки есть форма с hidden-полями: merchant_id, order_id, amount, description. Форма сабмитится на URL банка. Лжепокупатель может изменить order_id или amount и оплатить совсем другой счет и более того — на другую сумму.

(а) кто является атакующим — пользователь или третья сторона? Если третья сторона, то каким образом она меняет данные?
(б) зачем эта форма вообще показывается пользователю?
Сбрутить GUID?
См выше про длину инентификатора.
(а) кто является атакующим — пользователь или третья сторона? Если третья сторона, то каким образом она меняет данные?
(б) зачем эта форма вообще показывается пользователю?

мне кажется, что я уже не раз ответил на все эти вопросы и мы идем на очередной круг.
См выше про длину инентификатора.

Где «выше»?

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

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

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

habrahabr.ru/post/181372, раздел «Аутентификация сообщений с помощью HMAC». Ну или security.stackexchange.com/a/74552.
Соль вообще никак не влияет. А длина хэша… ну что ж, вы увеличили время подбора, да. Но вы не закрыли уязвимость.
Чтобы подобрать HMAC sha256 при помощи Timing attack придется отправить огромное количество запросов. Любая нормальная система заблокирует вас намного раньше чем вы успеете первые два символа подобрать :) Но это уже выходит за рамки текущего материала.
Система, описанная в вашем посте — заблокирует?
Обработка лимитов и алерты — это отдельная подсистема, не имеющая отношения к криптографии.
Правильно построенная система — да, заблокирует, если еще раньше не заблокирует WAF, не ограничит nginx по rate limit и т.п.
Вот поэтому решение, которое вы описываете в посте — уязвимо (и, собственно, является наглядной демонстрацией описанного по первой моей ссылке).

И при этом вы до сих пор не смогли показать, в каких случаях от него есть выгода.
Уязвимо в каком случае? Если можно безконтрольно брутить? Какое же решение в таком случае неуязвимо?
Уязвимо в каком случае? Если можно безконтрольно брутить? Какое же решение в таком случае неуязвимо?

Неуязвимых решений не бывает, бывают решения, которые уязвимы менее и более. Я вам указал на очевидную (и, в общем-то, сравнительно легко устранимую) уязвимость вашего. Просто что бы вы понимали: стоимость брутфорса вашего решения — k*n, решения, неподверженного тайминг-атаке — kn (где k — это временные затраты на перебор всех значений в одной позиции хэша, а n — количество позиций в хэше).
В теории — ОК. Но только я не понимаю, чем это решение более уязвимо, чем предложенные вами выше решение с "(а) просто идентификатором (б) идентификатором и паролем (ц) идентификатором и хэшом от пароля + nonce"
Ничем. Вопрос в том, зачем оно нужно вообще (в смысле, от какой атаки защищает).
Для рассматриваемого случая необходимо выполнить минимум 1024*256*256= 226 запросов. Пусть один запрос равен 1 КБ, тогда вам необходимо передать 65 ГБ информации к серверу (столько же на получение), чтобы вычислить HMAC для одного фиксированного сообщения на основе атаки по времени.

Вы можете сами расчитать вероятность того, что ни однин слой безопасности вас не отфильтрует (примеры). К тому же в нормальных приложениях используется метка времени, что даёт дополнительную защищаету от данной атаки.
Откуда вы взяли 1024*256*256?

Метка времени — это хорошо, но в данном случае ее нет.

(Я правильно понимаю, что вы считаете тайминг-атаку пренебрежимой опасностью?)
Опять же возвращаемся к статье:
Шум от задержек можно сглаживать двумя способами: ...


Предположения:
  • 1024 — количество запросов;
  • 256 — количество символов в байте;
  • 256 — количество байт в хэш-значении.


Метка времени — это хорошо, но в данном случае ее нет.

Автор описывает метод аутентификации данных (с заголовком статьи я не согласен), а не их хранение или формат. Поэтому комментарий не уместен.

(Я правильно понимаю, что вы считаете тайминг-атаку пренебрежимой опасностью?)

Я считаю атаку по времени ещё одним видом атаки, от которой существуют свои методы защиты.
Автор описывает метод аутентификации данных (с заголовком статьи я не согласен), а не их хранение или формат. Поэтому комментарий не уместен.

Как-то нелогично.

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

Я считаю атаку по времени ещё одним видом атаки, от которой существуют свои методы защиты.

Из которых самый простой — это просто закрыть дырку (не отдавать зависимое от времеи сравнение).
Приведу цитату из всё той же статьи:
Выглядит вполне безопасно, так ведь? Вы уверены?

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


Из которых самый простой — это просто закрыть дырку (не отдавать зависимое от времеи сравнение).

Вы знаете более безопасный метод, реализующий тот же самы функционал, чем описано в статье?
Вы имеете в виду — более безопасный, чем HMAC, или более безопасный, чем та реализация HMAC, которая описана в посте?

Чем реализация в статье плоха, с точки зрения ИБ, если не принемать во внимание атаку по времени?
(Ордеринг ключей уже указали)

Я других проблем не вижу, но это не означает автоматически, что их нет. У меня изначально больше претензий было к концепции (области применения), чем к реализации.
Любые системы безопасности, основанные на том что взломщик не может никак узнать общий ключ «просто потому что» — уязвимы.
Единственное применение — server-to-server over https, стоит по-моему упомянуть в статье что это не клиентская методика
HMAC много где используется (многие API многих сервисов, включая api вонтакте), ключ знает только сервис и апи-клиент, слово общий здесь некорректно. Почитайте как это сделано у амазона docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/HMACAuth.html

пока писал коммент, вы написали еще один — да, это совсем не для браузерного клиентсайда.
Первое правило криптографии — нельзя изобретать велосипеды в области криптографии.
Если у вас HTTPS и взаимодействие сервер-сервер, то, censored, почему вы не используете https с двусторонней проверкой сертификатов?
Пусть даже самоподписанных.
Для банк-клиента в «сферическом банке в вакууме» нужно не просто сгенерировать личный ключ и предоставить его банку, нужно, блин, распечатать его в шестнадцатеричном виде на бумаге в двух экземплярах, подписать, поставить печать и принести в банк лично — и только после этого банк-клиент заработает. Почему для того же самого, по сути, банк-клиента, только в виде модуля для CMS (то есть полностью автоматизированного и работающего в заведомо контролируемом третьей стороной (хостером) окружении), вы делаете кривой велосипед?
Потому что так принято «у больших», которые до сих пор пишут онл@йн через собаку?
Не могу говорить за всех, но HMAC тем не менее используется почти во всех API банков и платежных систем, которые мне доводилось встречать, а подключал я их очень много. Лишь у одного была проверка клиентского сертификата. И хоть убейте, я не считаю это решение практически уязвимым, брут хеша — это очень теоретическая уязвимость. На практике, после 10 неудачных попыток, любая нормальная система Ваш ip заблокирует, а инцидентом будет заниматься служба ИБ.
Было бы намного логичнее согласовывать данные платежа с банком напрямую, а в форму вставлять только какой-нибудь идентификатор транзакции. К тому же вам, по сути, нужно подписать данные, которые уходят только в одном направлении, а для этого можно использовать цифровую подпись, а не MAC. Плюсы очевидны: одна точка отказа вместо нескольких. А вот для подписи cookies такой MAC отлично бы подошёл.
Такие решения тоже бывают. Я вообще считаю что все взаимодействие должно происходить сервер-сервер, а пользователю должен выдаваться URL для перенаправления. Но существуют разные решения, и решение с формой и HMAC весьма популярно и много где встречается.
А форма при этом обязательно размещена на HTTPS?
См выше — HTTPS мы подразумеваем по-умолчанию.
Вы-то — да (и именно поэтому такое количество вопросов возникает). А банки, которые интегрируются описанным способом?
Да, во всех таких реализациях, которые я видел, форма сабмитится на банковский URL всегда по HTTPS.
Вопрос не только в том, куда форма сабмитится, но и в том (даже больше в том), как она доставляется клиенту.
Ну если учитывать, что клиентская сторона это в большинстве случаев страница чекаута в интернет-магазине, там скорее всего обычный HTTP, но я все же немного не улавливаю суть вопроса, на что это влияет, если форма в любом случае доступна пользователю браузера.
Это влияет на количество потенциальных атакующих сторон.

Если у вас страница чекаута доставляется по HTTP (буууу), то ее можно как угодно подменить в полете. А дальше мы прекрасно имеем атаку класса «возьми payload+HMAC от нужного нам заказа, сформируй страницу подтверждения с данными заказа жертвы, отправь на оплату нужного нам заказа». И как HMAC от этого защитит?

Я же не зря у вас спрашиваю, кто является атакующей стороной. Когда у вас HTTPS, их (сторон), условно, три: пользователь, браузер (зловредный или скомпроментированный), третья сторона с помощью уязвимости сайта (например CSRF). Когда у вас HTTP, сторон немедленно становится на одну больше.
Теперь я понял о чем вы. Безусловно, это так. И именно поэтому в наших решениях HTTPS используется абсолютно везде по-умолчанию, а HMAC/CSRF-токены (+ лимиты соединений) реализуют дополнительный слой для аутентификации и контроля логической целостности сообщений.
Я же не ленивый, я еще раз спрошу: от какой конкретно атаки и от кого вас защищает HMAC? (CSRF из рассмотрения исключаем, там HMAC — это всего лишь один из вариантов построения защиты, и не самый сильный)
Я тоже не ленивый, еще раз отвечу — от изменения пользователем данных формы. Разумеется, при условии, что контролируются лимиты.
То есть злоумышленник — пользователь. А сценарий у нас, насколько я помню, магазин и платежная система, между магазином и платежной системой нет предварительного обмена (т.е. платежная система принимает решение о том, что и куда оплачивать, на основании данных, приходящих с формы).

Вот вы доставили пользователю форму, в которой есть payload (идентификатор мерчанта, идентификатор заказа, сумма). Как он дальше может провести атаку? (я специально убрал HMAC, чтобы сделать возможной любую атаку подменой)
Вариантов масса, в зависимости от бизнес-логики интернет-магазина при обработке Result от платежной системы. Если интернет-магазин проверяет на Result только ID заказа и не проверяет сумму — вектор очевиден.
Ну так очевидно же, что проверять только идентификатор заказа — заведомая ошибка, и даже не только с точки зрения безопасности, но и с точки зрения бизнес-логики (платежные системы тоже ошибаются).
Нам с вами очевидно — мерчанту далеко не всегда. Я сам лично неоднократно встречал такие векторы и успешно их эксплуатировал.
В этом случае нужно исправлять эту ошибку, а не на форме добавлять контроль. Еще варианты?
Контроль на форме, навязанный платежной системой, как минимум, может защитить клиента-мерчанта от таких детских векторов, которым они, увы, зачастую подвержены.
Платежная система может навязать и проверку суммы платежа, вообще-то.

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


Очень странное предположение. Вроде описана задача контроля целостности данных, а решение приводится для задач, традиционно решаемых с помощью механизмов ЭЦП, которые решают несколько больше задач, чем просто контроль целостности, а именно:
— невозможность отказа от авторства, с одной стороны
— доказательство авторства, с другой.

При этом описан механизм, похожий на ЭЦП с использованием известного обеим сторонам ключа, который эти дополнительные задачи не решает:
— автор сообщения не может доказать, что он сообщения не писал, если ему предоставляют сообщение, подписанное общим ключом
— автор сообщения не может доказать что сообщение писал именно он, поскольку ключ известен обеим сторонам.

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

Да, действительно в теории так и есть. Но что же происходит в реальной жизни?

Оказывается, что банк является и сервером и центром сертификации в одном лице. Это приводит к тому, что, на практике, нет разницы система с открытым клюм или симметричная с меткой времени, так как секретный ключ пользователя известен банку при генерации пары открытый/секретный ключ.
UFO just landed and posted this here
JSON нельзя использовать для сериализации в подобных целях — он не гарантирует порядок сортировки полей в объекте (http://json.org/) Всё зависит от реализации библиотеки для конкретного языка.
Прочитайте статью внимательнее, там специально делается рекурсивная сортировка массива по ключам перед сериализацией в JSON и функция для этого написана.
Я прочитал достаточно внимательно. Вы пишете:
Почему именно JSON а не простой serialize PHP? Выбор в пользу JSON упал не случайно, поскольку это очень популярный формат сериализации, с которым будет легко работать не только в PHP, но и в любых других популярных языках программирования, таких как Java. Наша реализация должна быть предельно легко переносима на другие платформы и с использованием JSON-сериализации это будет сделать проще всего.

То что вы сортируете массив по ключам перед кодировкой его в JSON, ровно никак не гарантирует вам то что в JSON-е они буду иметь тотже порядок, вот выдержка из спецификации:
An object is an unordered set of name/value pairs.

Другими словами, hash полученный Вами в PHP и, например, в Java теоретически может отличаться, несмотря на одинаковую сортировку ключей перед кодированием в JSON.
Хм, интересно, на практике все работало нормально, нужно будет провести больше тестов.
Простой пример, в последний версиях Chrome и FF
JSON.stringify({a: 'a', 1: 1});
{"1":1,"a":"a"}

в PHP
echo json_encode(['a' => 'a', 1 => 1]);
{"a":"a","1":1}
Вы не думаете, что результат разный из-за разных ключей ('a' и a)?
А это не разные ключи, с точки зрения JSON они идентичны.
Sign up to leave a comment.

Articles