Страницы

Поиск по вопросам

Показаны сообщения с ярлыком token. Показать все сообщения
Показаны сообщения с ярлыком token. Показать все сообщения

пятница, 24 января 2020 г.

Как защититься от чрезмерной “пробивки” адресов через обработчик ajax запросов?

#xss #ajax #безопасность #token #форма


Есть форма, где одно из первых полей сразу после заполнения .on('blur') прозрачно
пробивается через БД сайта — зарегистрирован уже такой, или нет? В зависимости от результата,
прячется или показывается часть полей ниже.
Злодеи могут такой механизм задолбать массовыми запросами, в результате чего типа
получат инфу, которой у них быть не должно — отн. того, кто на сайте есть, а кого нет.
Как пока делаю: в сессии храню кол-во запросов. Если больше N — далее не обрабатываю,
все ответы негативны. Понятно, что можно сессию сбросить, через прокси заходить, через
Тор. Но, наверное, от полномасштабной пробивки это как-то защитит.
Как хочется делать: что-то типа защиты форм, где всякий раз генерится уникальный
токен, который можно использовать только раз.
Вопрос: как «правильно» защититься от совсем уж наглой и массовой пробивки данных
через обработчик ajax запросов?    


Ответы

Ответ 1



Подход с хранением количества запросов для определенных IP адресов как правило защищает неплохо, да и что-либо другое придумать тут крайне сложно. Можно лишь сменить уровень на котором проходит фильтрация и перенести эту задачу непосредственно на веб сервер. Если используете IIS, то есть специальный модуль: Dynamic IP Restrictions module. Думаю есть аналоги для Apache

четверг, 9 января 2020 г.

Смысл CSRF Token`а

#веб_программирование #token #csrf


Доброго времени суток! 

Изучаю csrf и не могу понять одну вещь, помогите пожалуйста разобраться.
На сайте learn.javascript есть статья по этому поводу. Там сказано:


  Типичный способ защиты сайтов – это «секретный ключ» (secret),
  специальное значение, которое генерируется случайным образом и
  сохраняется в сессии посетителя. Его знает только сервер, посетителю
  мы его даже не будем показывать.
  
  Затем на основе ключа генерируется «токен» (token). Токен делается
  так, чтобы с одной стороны он был отличен от ключа, в частности, может
  быть много токенов для одного ключа, с другой – чтобы было легко
  проверить по токену, сгенерирован ли он на основе данного ключа или
  нет.
  
  Для каждого токена нужно дополнительное случайное значение, которое
  называют «соль» salt.
  
  Формула вычисления токена:
  
  token = salt + ":" + MD5(salt + ":" + secret) Например:
  
  В сессии хранится secret="abcdef", это значение создаётся один раз.
  Для нового токена сгенерируем salt, например пусть salt="1234". token
  = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401".
Это значение – с одной
  стороны, случайное, с другой – имея такой token, мы можем взять его
  первую часть 1234 в качестве salt и, зная secret, проверить по
  формуле, верно ли он вычислен.
  
  Не зная secret, невозможно сгенерировать token, который сервер
  воспримет как правильный.
  
  Далее, токен добавляется в качестве скрытого поля к каждой форме,
  генерируемой на сервере.При её отправке сервер проверит поле csrf,
  удостоверится в правильности токена, и лишь после этого отошлёт
  сообщение.
  
  «Злая страница» при всём желании не сможет сгенерировать подобную
  форму, так как не владеет secret, и токен будет неверным.


Мне непонятно вот что:


secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый
раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним
вообще можно же получить доступ? Они хранятся же в файле где-то?
Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html
который пришел выдрать, заюзать его и отправить для своего запроса?
Я так понимаю смысл всей этой ерунды есть только тогда, когда либо


Сайт разрешает кросс-доменные запросы от всех Origin: *
либо
Злоумышленник мог ранее уже встроить форму на тот же сайт через XSS, чтобы оставаться
в том же домене, так как во всех остальных случаях у нас есть CORS, зачем нам CSRF?

Не понял, почему формула токена именно такая:

token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401"


Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль
1234 становится явно видна в токене!
Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет
токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем,
что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если
можно?)


Спасибо заранее за помощь!
Отличие от данного вопроса в том, что там так и не понятно, зачем нужен CSRF если
есть CORS
    


Ответы

Ответ 1



secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то? Только если у него есть доступ к компьютеру пользователя. Но тогда ему вообще CSRF не нужен, т. к. есть куда более простые способы отправить запрос самому. Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса? Только в случае MITM. При CSRF у хакера нет доступа к серверу, клиенту или каналу связи. я имею в виду разве он не может получить форму просто еще раз скриптом и этот токен потом отправить в своем запросе? Не может - тут сработает CORS. Если запрос get, то сервер его получит, но если он не пошлёт разрешающие заголовки, то запрашивающему скрипту браузер ответ не отдаст. А на POST вообще будет OPTIONS-запрос сначала. А если послать запрос не из браузера, а с сервера, то не будет авторизации пользователя и токен он опять же не получит. Я так понимаю смысл всей этой ерунды есть только тогда, когда либо Сайт разрешает кросс-доменные запросы от всех Origin: * либо ... Нет. Браузер позволит отправит форму, вот:
Не понял, почему формула токена именно такая: Форма может быть разной. Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене! Если соли нет, то ключ одного клиента подойдёт другому и хакер сможет использовать свой, поэтому нужна соль. Хм.. А вообще, что-то я задумался, есть тут сомнения... Разобрался: даже если хакер встроит свой валидный токен в форму, он не совпадёт с токеном в куках, поэтому форма будет отвергнута как поддельная. он не совпадет, потому что хакеру неизвестен id сессии, на основе котороой генерируется токен? Я имел в виду, что у хакера может быть свой токен, который корректен для него. Но этот токен не совпадёт с тем токеном, который лежит у другого пользователя в куках. А из чужих кук он его достать не может. Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?) Сайт не может залезть в чужие куки, поэтому подсмотреть нельзя.

Ответ 2



Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене! А ее и не нужно прятать. Она не для прямой секретности, а для двух других целей: Если результирующий хэш берется от пароля в чистом виде, то этот пароль можно подгадать по словарю. Случайная соль гарантирует, что по словарю этот секрет подобрать не удастся, а сгенерированный для одной соли словарь не подойдет для другой. В этом случае, конечно, предполагается что секрет у каждого клиента свой, иначе в случае подбора конкретного хэша есть риск, что там совпадет не только хэш, но и исходные данные, и тогда секрет будет известен атакующему Ресурсы, затрачиваемые хэш-функцией на создание хэша зависят от длины входной последовательности. Искусственно увеличивая входную последовательность, защищающийся повышает стоимость подбора совпадений для атакующего, потому что из-за маловероятности подбора коллизии случайным образом атакующий будет пробовать подобрать хэш, используя соль.

среда, 12 июня 2019 г.

Где хранить токены Android?

Есть веб сервер , который после успешной аутентификации отдает 2 токена (доступа и обновления) . Где их безопасно хранить? Shared Preferences с private mode не кажется мне лучшей идеей.


Ответ

Самый лучший вариант - использовать системный менеджер аккаунтов, который предоставляет возможность безопасно хранить данные пользователя и даже использовать их в нескольких приложениях одновременно. Есть замечательные статьи на эту тему:
Часть 1 - https://habrahabr.ru/company/e-Legion/blog/206210/
Часть 2 - https://habrahabr.ru/company/e-Legion/blog/216857/
А также документация - https://developer.android.com/training/id-auth/custom_auth.html

среда, 20 февраля 2019 г.

Смысл CSRF Token`а

Доброго времени суток!
Изучаю csrf и не могу понять одну вещь, помогите пожалуйста разобраться. На сайте learn.javascript есть статья по этому поводу. Там сказано:
Типичный способ защиты сайтов – это «секретный ключ» (secret), специальное значение, которое генерируется случайным образом и сохраняется в сессии посетителя. Его знает только сервер, посетителю мы его даже не будем показывать. Затем на основе ключа генерируется «токен» (token). Токен делается так, чтобы с одной стороны он был отличен от ключа, в частности, может быть много токенов для одного ключа, с другой – чтобы было легко проверить по токену, сгенерирован ли он на основе данного ключа или нет. Для каждого токена нужно дополнительное случайное значение, которое называют «соль» salt. Формула вычисления токена: token = salt + ":" + MD5(salt + ":" + secret) Например: В сессии хранится secret="abcdef", это значение создаётся один раз. Для нового токена сгенерируем salt, например пусть salt="1234". token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401". Это значение – с одной стороны, случайное, с другой – имея такой token, мы можем взять его первую часть 1234 в качестве salt и, зная secret, проверить по формуле, верно ли он вычислен. Не зная secret, невозможно сгенерировать token, который сервер воспримет как правильный. Далее, токен добавляется в качестве скрытого поля к каждой форме, генерируемой на сервере.При её отправке сервер проверит поле csrf, удостоверится в правильности токена, и лишь после этого отошлёт сообщение. «Злая страница» при всём желании не сможет сгенерировать подобную форму, так как не владеет secret, и токен будет неверным.
Мне непонятно вот что:
secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то? Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса? Я так понимаю смысл всей этой ерунды есть только тогда, когда либо
Сайт разрешает кросс-доменные запросы от всех Origin: * либо Злоумышленник мог ранее уже встроить форму на тот же сайт через XSS, чтобы оставаться в том же домене, так как во всех остальных случаях у нас есть CORS, зачем нам CSRF? Не понял, почему формула токена именно такая:
token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401"
Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене! Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?)
Спасибо заранее за помощь! Отличие от данного вопроса в том, что там так и не понятно, зачем нужен CSRF если есть CORS


Ответ

secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то?
Только если у него есть доступ к компьютеру пользователя. Но тогда ему вообще CSRF не нужен, т. к. есть куда более простые способы отправить запрос самому.
Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса?
Только в случае MITM. При CSRF у хакера нет доступа к серверу, клиенту или каналу связи.
я имею в виду разве он не может получить форму просто еще раз скриптом и этот токен потом отправить в своем запросе?
Не может - тут сработает CORS. Если запрос get, то сервер его получит, но если он не пошлёт разрешающие заголовки, то запрашивающему скрипту браузер ответ не отдаст. А на POST вообще будет OPTIONS-запрос сначала.
А если послать запрос не из браузера, а с сервера, то не будет авторизации пользователя и токен он опять же не получит.
Я так понимаю смысл всей этой ерунды есть только тогда, когда либо Сайт разрешает кросс-доменные запросы от всех Origin: * либо ...
Нет. Браузер позволит отправит форму, вот:


Не понял, почему формула токена именно такая:
Форма может быть разной.
Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене!
Если соли нет, то ключ одного клиента подойдёт другому и хакер сможет использовать свой, поэтому нужна соль.
Хм.. А вообще, что-то я задумался, есть тут сомнения...
Разобрался: даже если хакер встроит свой валидный токен в форму, он не совпадёт с токеном в куках, поэтому форма будет отвергнута как поддельная.
он не совпадет, потому что хакеру неизвестен id сессии, на основе котороой генерируется токен?
Я имел в виду, что у хакера может быть свой токен, который корректен для него. Но этот токен не совпадёт с тем токеном, который лежит у другого пользователя в куках. А из чужих кук он его достать не может.
Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?)
Сайт не может залезть в чужие куки, поэтому подсмотреть нельзя.

понедельник, 1 октября 2018 г.

Принцип работы Oauth2

Здравствуйте, сразу прошу извинить если вопрос глупый. Собственно сейчас разбираюсь с возможными вариантами авторизации с помощью REST API. Сейчас все социальные сети используют авторизацию OAuth/OAuth2. Прочитав немало статьей, все равно не очень хорошо отложилось в голове и есть много сомнений, что правильно понимаю.
Первое что это главные игроки, я не буду называть как в документации сказано, назову как понимаю.
Пользователь. Это владелец аккаунта который имеет доступ к каким-то ресурсам. Например Facebook/Twitter. Сервер авторизации OAuth/OAuth2. Это непосредственно сервер который производит выдачу разрешений на доступ к ресурсам(токены, "секреты"). Если взять пример из реальной жизни, то oauth.vkontakte.ru. Сервер расположен по такому домену(поддомен) сервера социальной сети Вконтакте. Сервер ресурсов. Это собственно сервер на котором хранятся данные для доступа к которым все это (Oauth авторизация) была придумана. Это могут быть различные данные, например фотки, музыка, записи из социальной сети. Приложение, может не всегда быть всем общепринятым приложением (программой) это может быть, а обычно так часто и есть, сервер. С помощью этого приложения пользователь хочет без пароля получить какие-то данные которыми он владеет. Например возьмем пример вконтакте или твитер. Чтобы использовать их API нужно зарегистрировать приложение у них на сайте ( в разделе разработчик), это подразумевает получения каких-то индентификаторов/ключей ... строк текста, с помощью которых можно запрашивать у пользователя разрешение на доступ к данным. Например, чтобы делать авторизацию на сайте через Вконтакте, нужно зарегистрировать приложение, получить ключи/токен, и в тот момент когда пользователь хочет выполнить вход через Вконтакте пересылать этот ключ на сервер. Или же приложение для мобильного устройства через которое пользователь будет производить вход и доступ к данным.
Теперь, как происходит авторизация, в моем понимании.
Допустим пользователь Х хочет зайти на сайт S через социальную сеть вконтакте. Разработчик сайта заранее предусмотрел возможность авторизации через социальные сети и зарегистрировал свой сайт как приложение вконтакте, получил ключик/токен. Пользователь, клацает на красивую кнопочку "Вход через Вконтакте". Что в этот момент происходит. Сайт(сервер) берет ранее полученный ключик, прикрепляет его к запрос и идет по ссылке, oauth.vk.com. (Передавая свой ключ в GET параметрах или POST не столь важно). Сервер oauth.vk.com смотрит, так такое приложение есть в базе, значит можно доверять. Теперь интересный момент, если пользователь был ранее авторизирован Вконтакте,то ему показывают всплывающее окошко, "Вы разрешаете приложению.....". А вот если пользователь ранее не производил вход Вконтакте, то ему сначала предлагают ввести свой пароль и логин, а уже затем спросят разрешает ли он приложению...... После этого если пользователь нажал "Да", то сервер oauth генерирует токен доступа, который является своеобразным временным паролем. Записывает в базу сам токен и например дату истечения. Возвращает этот токен серверу (сайт с которого пользователь хотел войти ВК) по адресу указанному в Callback, сервер смотрит, забирает токен записывает себе в базу данных рядом с именем пользователя. Если же нет, получает отказ в каком-то виде. Получив токен "приложение" имеет доступ к данным пользователя ( если нету ограничений на стороне сервера ресурсов). По сути если написать таким образом вредоносную программу, то можно после получения токен слить или удалить всю информацию пользователя. Имея данный токен. Мы можем использовать его в нескольких целях : использую как подтверждение того, что пользователь прошел авторизацию и теперь давать ему доступ к данным на нашем сайте (сайт с которого пользователь нажимал кнопку "Войти вконтакте") постоянно проверяя токен при доступе к приватным ресурсам на нашем сайте. То есть тот же пароль или сессия на стороне сервера (кукисы ...). Или же с помощью нашего сайта делать что-то на странице пользователя вконтакте, загружать фото, делать посты......
Теперь вопросы которые возникли у меня, кроме главного (правильно ли я вообще понимаю).
Если перехватить токен, то можно использовать его как тот же пароль. В чем тогда преимущество? Можно ограничить ресурсы разными токенами? Он временный и через некоторое время уже будет недействительным, но если злоумышленник успеет сделать что-то раньше ? То есть передавать токен как и пароль нужно в пост запросе по HTTPS протоколу, чтобы защищать его как тот же пароль? Если я использую токен от Вконтакте как авторизацию на своем сайте, то каким образом поучать новый токен по истечению срока действия старого, заново запрашивать " Вы разрешаете приложению .... " через oauth сервер. Такого не встречал на сайтах, обычно один раз разрешил и все. Данные способ авторизации удобен когда у пользователя есть какой-то глобальный аккаунт на доверенном сервере.Если же нужна авторизация на своем сервере только и без сторонних oauth серверов, следует использовать похожий принцип просто, при первой авторизации один раз передавать логин и пароль по HTTPS и получать токен уже непосредственно у сервера. Допустим интернет магазин и клиент Android.Первый раз логин и пароль, в ответ прилетает токен и доступ к API производить уже передавая этот токен. Регистрация приложения является дополнительным уровнем безопасности, то есть чтобы не все могли попросить пользователя разрешить им доступ и получить токен. Если приложение допускает авторизацию, как прямо на самом сервер (интернет магазин) так и через OAuth (вконтакте), то кто должен контроллировать время жизни токена во втором случае. В первом случае мы работаем непосредственно с нашими сервером(интернет магазин), а во втором случае мы передаем и используем токен полученный от внешнего сервера OAuth (vkontakte) каким образом нам нужно обновлять токен, просить об этом у oauth.vk.com или нам в данном Вконтакте больше не нужен, после выдачи первого токена и теперь сами на стороне сервера интернет магазина генеируем новые токены ?
Всем спасибо, кто дочитал это.
Скажите, правильно ли я вообще понимаю принцип работы? Если нет, то скажите пожалуйста где и что не так.
Спасибо всем огромное


Ответ

В принципе правильно, хоть и запутанно немного описываете. Там всё проще )
По остальным вопросам:
Нет, не так-же. Разница в правах.
Для авторизации обычно не требуют прав больших чем "возможность получить имя и фамилию пользователя". В диалоге аутентификации приложения пользователь видит все права, которые оно у него требует, и если не согласен, то может отказаться.
Ну и на уровне API обычно не предусматривают никаких критичных действий. Скажем, пароль или e-mail пользователя по access-токену практически нигде нельзя поменять. Да, очень желательно. Ну и большинство сервисов вообще не позволяют работать через незашифрованное соединение.
Впрочем, в случае explict-авторизации, кроме как между сервисом и вашим сервером access-токен никуда не передается. Т.е. при использовании незашифрованного соединения, перехватить токен может может только ваш хостер, либо провайдер вашего хостера. Что впрочем, тоже потенциально может быть неприятным. Делают обычно по другому - через запрос нового access-токена, используя статичный refresh-токен и старый access-токен.
Пользователь при этом ничего не видит, но access-токены постоянно заменяются на новые. У кого-то это происходит раз в день, а у кого-то раз в пару часов. Скомпрометированные токены при этом естественно становятся недействительными.
В случае получения запроса с некорректной комбинацией refresh-токена и access-токена, сервис автоматически должен сделать оба токена недействительными, ну и соответственно в этом случае пользователь увидит окошко аутентификации приложения заново.
Но это если сервис вообще выдает refresh-токены. К сожалению они опциональны, и ВКонтакте не выдает их, в отличии от Google и Facebook. В этом случае можно только периодически запрашивать что-то доступное вашему приложению. После истечения срока токена, сервис будет выдавать в ответ ошибку 400 с error=invalid_grant - в этом случае приложение должно снова перекинуть пользователя на форму аутентификации приложения на сервисе, дабы получить новый access-токен. Да, так. Так многие и делают.
По похожему принципу, кстати, работает авторизация на большинстве сайтов ещё со времен создания интернета. Логин-пароль передаются сервису только один раз, возвращается некий токен(например хеш чего-либо), он сохраняется в некое хранилище(например в cookies), ну и собственно этот токен используется используется для авторизации в последующие разы. Пресловутые же email и пароль по такому токену менять не позволяют. Не только. Основная цель регистрации приложений - дать возможность администрации отключить всё приложение разработчика в связи с выполнением приложением каких-то вредоносных действий, или в случае массовой компрометации access-токенов пользователей этого приложения. Нет, не на самом сервере приложения. Сервер приложения просто отправляет сервису запрос на refresh, и в ответ получает новый access-token.