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: originalpassUn 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@tornadoXse trunca automáticamente a 13 caracteres, resultando enjacob@tornado.Si no hay una restricción
UNIQUEen la columnausername, 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:
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.
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:
| username | password |
|---|---|
| jacob@tornado | originalpass |
| jacob@tornado | attackerpass |
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
- 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'; [mysqld]
sql_mode=STRICT_ALL_TABLES INSERT INTO users (username, password) VALUES ('jacob@tornadoX', 'attackerpass');ERROR 1406 (22001): Data too long for column 'username'- Validación en el lado del servidor
Nunca confíes solo enmaxlengthdel HTML. Verifica en el backend que la longitud del username no exceda los 13 caracteres. - Agregar restricción
UNIQUE
ALTER TABLE users ADD UNIQUE (username);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
maxlengthsolo 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
UNIQUEy monitoreo de advertencias de truncamiento.CWE principal: CWE-20, Improper Input Validation.