Seguridad de Formularios: Prevenir solicitudes no deseadas con PHP

30/07/2024 | HTML, PHP, Seguridad | 0 comentarios

Protege tus formularios PHP de ataques comunes con estrategias efectivas: tokens CSRF, CAPTCHAs, honeypots y validación de datos.

Descargar archivos


Proteger los formularios web contra solicitudes no deseadas, como ataques CSRF (Cross-Site Request Forgery) o envíos masivos, es esencial para mantener la seguridad y la integridad de tu aplicación. Veamos algunas estrategias y técnicas para lograrlo utilizando PHP.

Protección contra CSRF

Un ataque CSRF se produce cuando un atacante usa la cuenta de un usuario autenticado para realizar una acción no deseada, por ejemplo enviar datos modificados al servidor. Para protegerse contra este tipo de ataques, puedes implementar un token CSRF.

Implementar un token CSRF:

Genera un token único cuando se carga el formulario y almacénalo en la sesión del usuario.


<?php
// file: form.php

session_start();
if (empty($_SESSION['token'])) {
    $_SESSION['token'] = bin2hex(random_bytes(32));
}

Incluye el token como un campo oculto en tu formulario.


<form method="POST" action="process.php">
    <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
    <!-- Otros campos del formulario -->
    <button type="submit">Enviar</button>
</form>

Al procesar el formulario verifica el token recibido es igual al token en la sesión.


<?php
// file: process.php

session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
   // validate token
   if (!hash_equals($_SESSION['token'], $_POST['token'])) {
      die('Token no válido');
   }

   // Regenerate token
   $_SESSION['token'] = bin2hex(random_bytes(32));

   // Process form
}

Protección contra Envíos Masivos / Spam

Los bots automatizados pueden enviar formularios repetidamente, esto puede generar spam o ataques de denegación de servicio. Para evitar este tipo de ataques se pueden usar Captchas o Honeypots.

CAPTCHA

Implementa un CAPTCHA para verificar que el usuario es humano. Puedes usar reCaptcha que ofrece diversas formas para validar si el usuario es un humano.

Implementar Google reCaptcha

Lo primero es registrarse para usar el servicio y obtener las llaves del servicio SITE_KEY y SECRET_KEY. Lo siguiente es agregar un campo oculto g-recapcha con el valor de la llave pública:


<form method="POST" action="process.php">
   <div class="g-recaptcha" data-sitekey="SITE_KEY"></div>
   <!-- Otros campos del formulario -->
   <button type="submit">Enviar</button>
</form>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Luego, al procesar el formulario primero validamos que el reCaptcha es válido.


<?php
// file: process.php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $secret = 'SECRET_KEY';
    $request = $_POST['g-recaptcha-response'];
    $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$request";

    $response = file_get_contents($url);
    $responseData = json_decode($response);

    if (!$responseData->success) {
        die('CAPTCHA no válido');
    }

    // Procesar el formulario
}

Honeypot

Un honeypot es un campo oculto de un formulario que los usuarios no pueden ver ni llenar. Sin embargo, los bots de spam, completan todos los campos de un formulario, lo que permite detectar y bloquear estos envíos automatizados.

Implementar Honeypot

Añade un campo oculto vacío al formulario que deseas proteger.


<form method="POST" action="process.php">
   <div style="display:none;">
       <input type="text" id="honeypot" name="honeypot">
   </div>
   <!-- Otros campos del formulario -->
   <button type="submit">Enviar</button>
</form>

Luego, al procesar el formulario primero validamos que el campo honeypot debe estar vacío.


<?php
// file: process

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!empty($_POST['honeypot'])) {
        die('Solicitud inválida');
    }

    // Procesar el formulario
}

Validar y filtrar datos

Independientemente de las técnicas anteriores, siempre filtra y valida los datos enviados por el formulario usando filter_input, esto para prevenir inyecciones y otros tipos de ataques.


$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
if (empty($name)) {
   die('Nombre es requerido');
}

$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
   die('Email no válido');
}

Conclusión

Proteger tus formularios contra solicitudes no deseadas es importante para mantener la seguridad de tu aplicación web. Implementar tokens CSRF, CAPTCHAs, campos honeypot y validar y sanitizar los datos son técnicas efectivas para mitigar estos riesgos.

Referencias

Envíar Comentario

En este sitio los comentarios se publican previa aprobación del equipo de Kodetop. Evita los comentarios ofensivos, obscenos o publicitarios. Si deseas publicar código fuente puedes hacerlo entre las etiquedas <pre></pre>