cd ~/blog

~/vulns/sql-truncation-attack.md

SQL Truncation Attack

web 24-08-2025
SQLtruncationtornadoSQL-Truncation

~2 min de lectura


Ataque de truncamiento en bases de datos

Cuando analizamos formularios web, a veces encontramos atributos HTML como este:

<input type="text" name="uname" placeholder="email" maxlength="13" />

El atributo maxlength="13" indica que el navegador no permitirá que el usuario escriba más de 13 caracteres en ese campo. Sin embargo, esto solo es una validación del lado del cliente. Un atacante puede modificar el HTML en el navegador o usar herramientas como Burp Suite, curl o DevTools para enviar más de 13 caracteres al servidor. Por eso, nunca se debe confiar únicamente en maxlength para proteger la base de datos.


Implicaciones en la base de datos

Si un formulario tiene un maxlength de 13 caracteres, probablemente la columna en la base de datos también tenga un límite similar:

CREATE TABLE users (
  username VARCHAR(13),
  password VARCHAR(100)
);

Si el backend no valida la longitud de la entrada, la base de datos trunca automáticamente cualquier valor que exceda los 13 caracteres. Esto puede generar vulnerabilidades de colisión o sobrescritura de datos.


Cómo se puede explotar

Supongamos que existe un usuario registrado:

username: jacob@tornado
password: originalpass

Un atacante podría intentar registrar un usuario con un nombre más largo:

INSERT INTO users (username, password) VALUES ('jacob@tornadoX', 'attackerpass');
  • En bases de datos como MariaDB o MySQL sin modo estricto, el nombre jacob@tornadoX se trunca automáticamente a 13 caracteres, resultando en jacob@tornado.

  • Si no hay restricción ==UNIQUE== en la columna username, se permite la inserción y ahora hay dos registros con el mismo nombre truncado.

  • Incluso si hay restricción UNIQUE, pero sin modo estricto, puede generarse advertencia sin bloquear la inserción.

Esto permite al atacante:

  1. Sobrescribir la cuenta existente si la lógica de la aplicación reemplaza registros.

  2. Autenticarse en la cuenta original si la aplicación hace SELECT ... LIMIT 1, devolviendo el registro del atacante.

Ejemplo de resultado de la tabla:

usernamepassword
jacob@tornadooriginalpass
jacob@tornadoattackerpass

Prevención

  1. Activar modo estricto en MariaDB/MySQL
    Esto evita truncamientos silenciosos y genera error al insertar datos demasiado largos:
 SET GLOBAL sql_mode = 'STRICT_ALL_TABLES';
En archivo de configuración:
 [mysqld]
sql_mode=STRICT_ALL_TABLES
Ahora, un intento de insertar un nombre más largo:
	INSERT INTO users (username, password) VALUES ('jacob@tornadoX', 'attackerpass');
ERROR 1406 (22001): Data too long for column 'username'
  1. Validación en el lado del servidor
    Nunca confíes solo en maxlength del HTML. Verifica en el backend que la longitud del username no exceda los 13 caracteres.
  2. Agregar restricción UNIQUE
 ALTER TABLE users ADD UNIQUE (username);
Esto impide duplicados, pero no reemplaza la validación de longitud ni el modo estricto.
  • Monitoreo de truncamientos
    Habilitar logs para detectar advertencias por truncamiento ayuda a identificar intentos de ataque.
  • Resumen

    • El atributo maxlength solo protege en el frontend, no en el servidor.

    • Si la base de datos trunca silenciosamente los valores, pueden generarse colisiones.

    • Esto se conoce como SQL Truncation Attack: el atacante envía datos más largos que la columna, se truncan y pueden sobrescribir registros o autenticarse sin conocer la contraseña original.

    • La prevención requiere: validación del lado servidor, modo estricto, restricciones UNIQUE y monitoreo de advertencias de truncamiento.

    // relacionados