Интерфейс API предотвращает фальсификацию параметров и атаки воспроизведения

задняя часть

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

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

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

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

Общие меры безопасности для API-интерфейсов в основном включают следующее:

  • предотвратить внедрение sql
  • предотвратить xss-атаки
  • Предотвращение подделки параметров запроса
  • предотвратить повторные атаки

Основные меры защиты можно свести к двум пунктам:

  • Проверить обоснованность запроса
  • Подтвердить запрошенные данные

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

Защита от несанкционированного доступа к параметрам запроса

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

В интерфейсе API, помимо использования протокола https для связи, нам также необходимо иметь собственный набор механизмов шифрования и дешифрования для защиты запрашиваемых параметров и предотвращения их подделки.

Процесс выглядит следующим образом:

  1. Клиент использует согласованный секретный ключ для шифрования передаваемых параметров, получает подпись значения подписи, помещает значение подписи в запрошенные параметры и отправляет запрос на сервер.
  2. Сервер получает запрос клиента, а затем использует согласованный ключ для повторной подписи запрошенных параметров (кроме подписи) для получения автографа значения подписи.
  3. Сервер сравнивает значения подписи и автографа, и если сравнение непротиворечиво, запрос считается легитимным. Если сравнение несовместимо, это означает, что параметры были изменены, и это считается законным запросом.

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

предотвратить повторные атаки

Решение на основе временных меток

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

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

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

решение на основе nonce

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

Мы каждый раз сохраняем запрошенный параметр nonce в «коллекции», которая может храниться в базе данных или кэшироваться в формате json.

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

Параметр nonce был сохранен в коллекции на сервере при выполнении первого запроса, а второй запрос будет распознан и отклонен.

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

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

Схема на основе метки времени и одноразового номера

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

Процесс проверки интерфейса API:

String token = request.getHeader("token");
String timestamp = request.getHeader("timestamp");
String nonceStr = request.getHeader("nonceStr");

String url = request.getHeader("url");

String signature = request.getHeader("signature");


if(StringUtil.isBlank(token) || StringUtil.isBlank(timestamp) || StringUtil.isBlank(nonceStr) || StringUtil.isBlank(url)
|| StringUtil.isBlank(signature))
{
    return;
}

UserTokenInfo userTokenInfo = TokenUtil.getUserTokenInfo(token);

if(userTokenInfo == null){
    return;
}

if(!request.getRequestURI().equal(url)){
return;
}

if(DateUtil.getSecond()-DateUtil.toSecond(timestamp) > 60){
    return;
}

if(RedisUtils.haveNonceStr(userTokenInfo,nonceStr)){
    return;
}

String stringB = SignUtil.signature(token, timestamp, nonceStr, url, request);
if(!signature.equals(stringB)){
    return;
}
RedisUtils.saveNonceStr(userTokenInfo,nonceStr,60);

Как гарантировать, что публичная учетная запись WeChat не будет атакована повтором

Чтобы использовать интерфейс общедоступной платформы WeChat, вам необходимо установить токен на общедоступной платформе WeChat. Здесь предполагается, что токен не будет известен злоумышленнику, что эквивалентно PSK (Pre Shared Key). В отправке сообщений WeChat есть три параметра: подпись, временная метка и одноразовый номер.

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

$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
// 按照$token,$timestamp,$nonce的顺序组成数组
$tmpArr = array($token, $timestamp, $nonce);
// 按照字典序排序
sort($tmpArr, SORT_STRING);
// 将排序后的数组串成字符串
$tmpStr = implode( $tmpArr );
// 用sha1计算签名
$tmpStr = sha1( $tmpStr );
// 校验签名
if( $tmpStr == $signature ){
    return true;
}else{
    return false;
}

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

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

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