Prevenindo ataques de repetição (Replay Attack) no PHP

Métodos eficazes para evitar ataques de repetição no PHP, protegendo requisições contra reutilização indevida e ataques maliciosos.

Introdução

Ataques de repetição (Replay Attack) ocorrem quando um atacante captura e reenvia requisições legítimas para obter acesso não autorizado ou repetir ações sem o conhecimento do usuário. Isso pode comprometer transações financeiras, autenticações e outras ações críticas em aplicações PHP.

1. Implementando tokens únicos (Nonce)

O uso de Nonce (Number Used Once) impede que a mesma requisição seja reutilizada. Podemos gerar um token único para cada requisição:

session_start();
if (!isset($_SESSION['nonce'])) {
    $_SESSION['nonce'] = bin2hex(random_bytes(16));
}

Esse token deve ser enviado junto à requisição e validado no servidor:

if ($_POST['nonce'] !== $_SESSION['nonce']) {
    die("Requisição inválida! Token não reconhecido.");
}
unset($_SESSION['nonce']);

Isso garante que cada requisição seja válida apenas uma vez.

2. Usando timestamps para expiração de requisições

Outra forma de evitar ataques de repetição é incluir um timestamp na requisição e definir um tempo limite para aceitação:

$tempo_requisicao = intval($_POST['timestamp']);
if (time() - $tempo_requisicao > 60) {
    die("Requisição expirada!");
}

Isso impede que uma requisição seja reutilizada após um período curto.

3. Implementando assinaturas digitais

Podemos gerar uma assinatura digital para cada requisição utilizando uma chave secreta:

$chave_secreta = 'minha_chave_secreta';
$assinatura = hash_hmac('sha256', $_POST['dados'] . $_POST['timestamp'], $chave_secreta);

O servidor verifica se a assinatura recebida é válida:

if ($_POST['assinatura'] !== $assinatura) {
    die("Assinatura inválida!");
}

Isso impede que a requisição seja alterada ou repetida sem autorização.

4. Armazenando e validando requisições já processadas

Para evitar que a mesma requisição seja executada mais de uma vez, podemos armazenar um identificador único no banco de dados:

$id_requisicao = $_POST['id_requisicao'];
$stmt = $pdo->prepare("SELECT COUNT(*) FROM requisicoes WHERE id = ?");
$stmt->execute([$id_requisicao]);
if ($stmt->fetchColumn() > 0) {
    die("Requisição já processada!");
}

Se a requisição for única, armazenamos seu identificador para impedir reprocessamentos futuros.

Conclusão

A prevenção contra ataques de repetição no PHP envolve o uso de Nonce, timestamps, assinaturas digitais e controle de requisições já processadas. Essas medidas garantem que cada requisição seja válida apenas uma vez, evitando reutilizações indevidas e acessos não autorizados.

Requisições repetidas representam um risco para a integridade de aplicações PHP, especialmente em transações financeiras, sistemas de autenticação e APIs. Se um atacante capturar uma requisição legítima, ele pode reutilizá-la para acessar informações sensíveis ou realizar ações não autorizadas.

A melhor maneira de mitigar esse problema é garantir que cada requisição seja única e tenha um tempo de validade. Métodos como Nonce, timestamps e assinaturas digitais garantem que requisições não possam ser repetidas ou modificadas sem detecção. Além disso, armazenar identificadores únicos de requisições processadas evita que ações críticas sejam executadas mais de uma vez.

A implementação correta dessas práticas reduz o risco de ataques de repetição e fortalece a segurança da aplicação, garantindo maior confiabilidade para os usuários.

Algumas aplicações:

  • Evitar que pagamentos sejam processados mais de uma vez.
  • Proteger APIs contra requisições duplicadas.
  • Impedir reutilização de tokens de autenticação.
  • Garantir que transações críticas sejam executadas apenas uma vez.

Dicas para quem está começando

  • Utilize tokens Nonce para garantir que cada requisição seja única.
  • Inclua timestamps e limite o tempo de validade das requisições.
  • Implemente assinaturas digitais para evitar modificações em requisições.
  • Armazene identificadores de requisições já processadas para evitar duplicações.
  • Registre logs de requisições suspeitas para monitoramento e análise de segurança.

Contribuições de Renata Oliveira

Compartilhe este tutorial: Como impedir ataques de repetição (Replay Attack) em requisições PHP?

Compartilhe este tutorial

Continue aprendendo:

Como garantir a segurança da autenticação de usuários no PHP?

Métodos para garantir a segurança da autenticação de usuários no PHP, evitando vulnerabilidades e acessos indevidos.

Tutorial anterior

Como validar tokens de segurança em aplicações PHP?

Métodos para validar tokens de segurança em aplicações PHP, garantindo que apenas usuários autorizados possam acessar recursos protegidos.

Próximo tutorial