cd ~/blog

~/vulns/sql-truncation-attack.md

SQL Truncation Attack

webautor: Jordy Pérez Osorio aviso legal
SQLtruncationtornadoSQL-Truncation

~4 min de lectura


1. Descripción técnica

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.


2. Impacto

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, algunas configuraciones de la base de datos pueden aceptar el valor con una advertencia y almacenarlo truncado. No es un comportamiento universal: el motor, el tipo de columna y el modo SQL determinan si la operación se rechaza o continúa. Cuando el valor truncado coincide con un identificador existente y la aplicación no aplica restricciones de unicidad adecuadas, puede producirse una colisión entre cuentas.


3. Condiciones necesarias y mecanismo

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 una restricción UNIQUE en la columna username, la tabla puede aceptar dos registros con el mismo nombre resultante.

  • Si existe una restricción UNIQUE, la colisión normalmente provoca un error de clave duplicada. El modo no estricto no convierte esa restricción en una advertencia inocua.

Si la inserción duplicada se acepta, el impacto depende de cómo la aplicación resuelva la autenticación y las actualizaciones. Entre los resultados posibles se encuentran:

  1. Modificar una cuenta existente únicamente si la lógica de la aplicación ejecuta una operación de actualización o reemplazo sobre el identificador truncado.

  2. Alterar la selección de credenciales si la consulta de autenticación admite duplicados y selecciona uno de ellos sin un criterio inequívoco.

Ejemplo de resultado de la tabla:

usernamepassword
jacob@tornadooriginalpass
jacob@tornadoattackerpass

4. Validación y detección

La comprobación debe realizarse con una cuenta de prueba y sin afectar registros reales. Primero se compara la longitud admitida por el backend con la longitud de la columna. Después se envía un valor que exceda ese límite y se revisan la respuesta de la aplicación, las advertencias del motor y el valor realmente almacenado. La vulnerabilidad solo queda confirmada si la entrada se trunca y la lógica de identidad permite aprovechar la colisión.

Los registros de la base de datos y de la aplicación deben alertar sobre errores como Data too long, advertencias de truncamiento e intentos repetidos de registrar identificadores con prefijos coincidentes.

5. Mitigació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.
  • 6. Explotación documentada en 004-tornado

    En Tornado, el límite maxlength del formulario podía omitirse al modificar la petición. El valor enviado superaba la longitud esperada por la aplicación y terminaba colisionando con el nombre de una cuenta existente después del truncamiento. La cadena dependía tanto de la aceptación del valor por la base de datos como de la forma en que la aplicación consultaba los registros; maxlength por sí solo no constituía una protección.

    7. Clasificación

    • 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 y busca que el valor almacenado colisione con otro identificador.

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

    • CWE principal: CWE-20, Improper Input Validation.

    8. Referencias

    // relacionados