Подтвердить что ты не робот

Как защитить запросы Ajax-ссылок?

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

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

Итак, когда пользователь закончил заполнять поле электронной почты, запрос Ajax отправляется на сервер, что-то вроде следующей ссылки:

example.com/[email protected]

Когда check.php получает электронное письмо, он запрашивает базу данных, если она существует или нет, и возвращает сообщение типа: User already exists, если пользователь существует, или null, если пользователь не существует.

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

Кто-то может сделать огромный цикл для проверки электронной почты, например:

//Getting the response of the next links
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns User already exists

-------------------------------------------- -------------------------------------------------- --------------------------------------

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

Прежде чем выполнять ЛЮБОЙ запрос ajax на сервер, я запрашиваю токен на сервере. Этот токен выглядит так: fmf5p81m6e56n4va3nkfu2ns8n он сделан простым методом, однако он может быть более сложным, но это хорошо.

public String getToken() throws UnsupportedEncodingException {
    return new BigInteger(130, new SecureRandom()).toString(32);
}

При запросе маркера сервер не только возвращает токен, но также и небольшой script, который в случае, если кто-то использует браузер для проверки элемента (и браузера navbar), и будет запускаться script, а токен будет очиститься. Сервлет возвращает что-то вроде этого:

_html += "<head>"
    + "<script> "
    + "window.onload=function(){\n"
    + "       document.body.innerHTML = \"\";\n"
    + "    }"
    + "window.location.href='http://mywebsite.com' "
    + "</script>"
    + "</head>"
    + "<body>"
    + "[" + token+ "]"
    + "</body>"
    + "</html>";

Сначала опустошает тело, затем переместится туда, где мы хотим. javascript/jquery, однако, поймает весь контент как строку, тогда я просто извлекаю строку между [и]. Этот токен доступен только для следующего запроса, поэтому каждый запрос AJAX будет иметь свой уникальный токен. Во втором запросе только что использованный токен удаляется.

После того, как я получу токен, я добавляю его как параметр в любую ссылку, которую я запрашиваю, примерно так:

ajaxRequestObjet = $.ajax({
    url: "http://localhost:8084/mywebsite.com/servlet", //<-- local tomcat server
    method: "POST",
    data: "type=AJAX&page=some-article&token=fmf5p81m6e56n4va3nkfu2ns8n"
});

Этот метод отлично работает с тем, кто проверяет веб-сайт вручную и пытается использовать ссылки, но как насчет серверов java/php/IIS, которые делают это автоматически?

Для этого попросите заголовок! Что-то вроде этого:

boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); 

Это будет истинно только и только если существует XMLHttpRequest....

Есть одна последняя вещь, о которой нужно помнить. Убедитесь, что 'Access-Control-Allow-Origin' header is NOT present in your app убедитесь, что любой javascript NOT на вашем сервере не получит ресурсы сервера. Если этот заголовок не существует, хром вернет это:

XMLHttpRequest cannot load http://localhost:8084/mywebsite.com/servlet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

Java-сервер был в tomcat, и у меня был другой apache для этих тестов, это маленький html, присутствующий в apache, который дал ошибку выше:

<html>
<head>
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>

    <script>
    ajaxRequestObjet = $.ajax({
        url: "http://localhost:8084/mywebsite.com/servlet",
        method: "POST",
        data: "type=AJAX&page=Token"
    });

    ajaxRequestObjet.done(function (msg) { 
        alert(msg);
    });

    </script>

</head>
<body>
</body>
</html>
4b9b3361

Ответ 1

Пока вы не можете управлять этим 100%... есть несколько вариантов.

Попробуйте использовать те же методы, что и пользователи с скриптами Captcha.

В основном, когда пользователь загружает форму/страницу. Вы генерируете случайную строку/идентификатор в своем сеансе PHP и сохраняете его. Когда они отправляют запросы ajax, попробуйте выполнить проверку ajax, добавив строку /id и потребовав ее прежде чем разрешить проверку выполнить else, верните заголовок 500 или что-то в этом роде.

Используя этот подход с сеансами, вы можете установить допустимый предел проверок (скажем, 5) и после того, как пользователь попробовал более 5 проверок, они должны перезагрузить страницу или выполнить проверку человека (например, Captcha). Затем он сбрасывает их количество. Даже разрешите в общей сложности сказать 30 в течение 1 часа/за IP или что-то в этом роде.

Также используйте интеллектуальные события для запуска, когда выполняется проверка ajax, например, изменение поля/вкладки или нажатие кнопки. Или, когда обнаружен действительный адрес электронной почты.. но скажите, что .com.au будет срабатывать дважды.

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

Помимо этого, вам нечего делать гораздо легче. Но есть еще несколько других идей.

Большинство из них будут работать с использованием сеанса PHP/cookie. Скажите, например, если они проверяют и находят 3 адреса электронной почты. Затем вы устанавливаете это как ограничение и заставляете их требовать ручную подачу или что-то в этом роде.

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

Задержки времени будет просто выглядеть плохо/сделать ваш сайт медленным/ошибка пользователя с ожиданием ответа.

Вам нужно ограничить количество поисковых запросов на сеанс/IP-адрес. В противном случае всегда есть способ пройти эти проверки. В принципе, когда они достигают предела. Заставьте пользователя /ip/session ждать несколько минут/часов и проверить их с помощью Captcha script, чтобы он не был написан по сценарию...

Защита Javascript/скрытие источника

Пока вы не можете сделать это по-настоящему, вы можете сделать некоторые вещи, создавая JS, используя страницу PHP с заголовком JS.. поэтому <script src='myjscode.php'></script>, и это позволяет PHP проверять действительный сеанс. Поэтому останавливает внешние запросы на в какой степени. Но это в основном полезно для того, чтобы позволить JS быть доступным только за членством/логином.

Несколько проверок/если возможно в этом случае

В зависимости от вашего подхода, это для пользователя, чтобы проверить, есть ли у них учетная запись? Если это так, вы можете совместить проверку электронной почты с чем-то вроде имени/страны/возраста/доба... Поэтому им нужно выбрать два или три правильных совпадающих значения, прежде чем они смогут получить чек/ответ от вызова ajax?

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

Ответ 2

Код JavaScript на вашем веб-сайте выполняется на компьютере пользователя, поэтому вы не можете остановить его от копирования кода. Даже если вы используете обфускатор кода (например, https://www.javascriptobfuscator.com/), хакер может отлаживать ваше приложение и записывать все запросы, отправляемые на сервер.

Все необходимое для безопасности должно произойти на сервере. Вы можете ограничить количество запросов с определенного IP-адреса.

Ответ 3

Прежде всего: я бы URL-кодировал почтовый адрес. 'example.com/check.php?email=' . urlencode([email protected])

Задайте свой вопрос: когда вызывается check.php, вы можете

  • проверить, если пользовательский сеанс и его IP-адрес отправили запрос в течение последних секунд
  • если нет, напишите сеанс пользователя, IP-адрес пользователя и текущую временную метку в вспомогательную таблицу плюс к файлу cookie и нажмите на свой DB
  • если да, заблокируйте запрос

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

Ответ 4

Вы можете защитить от нападений грубой силы чем-то вроде токены CSRF:

Назначьте идентификатор сервера для каждого сеанса клиента. Каждый запрос check.php должен включать этот идентификатор.

check.php должен отклонять запросы, не содержащие идентификатор, или включать идентификатор, который сервер не генерировал (чтобы предотвратить атаки с поддельными идентификаторами). Он также должен оценивать ограничение на идентификатор - если данный идентификатор сделал запрос в (скажем) последней секунде, или заданный идентификатор делает больше, чем n запросов за 10 секундный интервал, он должен вернуть ответ об ошибке. Это защищает запросы от одного сеанса, поступающего с нескольких IP-адресов.

Вы также должны оценить предел по IP-адресу, чтобы предотвратить принудительное принудительное использование, открыв большое количество сеансов веб-приложений.

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

Ответ 5

Этот тип атаки можно рассматривать так же, как и любую другую атаку грубой силы, где единственным эффективным решением является использование Captcha, Но, конечно же, Captchas вредит UX, поэтому вам нужно подумать, стоит ли дополнительная безопасность, особенно для атаки, которая вряд ли произойдет в любом случае. Тем не менее, вы можете использовать Captcha в своей регистрационной форме, чтобы предотвратить создание ботов от ботов.

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

CloudFlare

Не так хорошо, как решение Captcha, но атака грубой силы может быть обнаружена и предотвращена системой Cloudflare DDoS. Кроме того, CF может заставить Tor пользователей решить Captcha перед доступом к вашему сайту, что помешало бы злоумышленнику использовать Tor в качестве транспортного средства для атаки.

Ограничение скорости IP

Ограничение скорости на основе IP имеет проблемы, потому что если злоумышленник решил выполнить такую ​​огромную задачу, он, скорее всего, будет использовать Botnet или какой-либо другой системы с несколькими компьютерами для запуска атаки.

Рассмотрим большую организацию, такую ​​как Университет, где все пользователи используют публичный IP-адрес. Один из пользователей запускает атаку на ваш сайт и блокирует его IP-адрес, а также процессы, блокирующие всех остальных. Эта контрмера действительно может быть использована для запуска атаки DoS.

Идентификатор сеанса /CRSF

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

Ответ 6

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

Ответ 7

Вы можете использовать CSRF token и выйти из своего script, если вы обнаружите, что нет или недействительно CSRF token. Почти (если не все) фреймворки PHP получают поддержку для этого.

Также проверьте этот вопрос у сообщества безопасности: https://security.stackexchange.com/info/23371/csrf-protection-with-custom-headers-and-without-validating-token