El fallo más común en los portales es invisible para cualquier escáner

  • 2 min di lettura

Un portal de clientes. Un usuario real, con acceso correcto, abre un documento suyo. La dirección es algo como /api/documentos/4187.

Cambia el número. 4186. Y ve el contrato firmado de otra empresa.

Es el primer punto de la clasificación de OWASP para API, se llama Broken Object Level Authorization, y lo encontramos en buena parte de los portales a los que nos llaman.

Por qué ningún escáner lo encuentra

Porque técnicamente no hay ningún error. El programa hace exactamente lo que se le ha pedido: se le ha pedido el documento 4186, y devuelve el documento 4186. No se cae, no produce avisos, responde 200.

Una herramienta automática busca patrones conocidos: entradas sin filtrar, versiones viejas, configuraciones equivocadas. No puede saber que ese documento no es de quien lo está pidiendo, porque esa información está en vuestro modelo de negocio, no en el código.

Cómo se escribe por error

Así:

if (!usuario_autenticado()) {
    return null;
}

return db()->fila('SELECT * FROM documentos WHERE id = ?', [$id]);

Un control hay, y es el que todos esperan ver: sin acceso no se pasa. Pero la pregunta a la que responde la última línea es «¿existe el documento 4186?», no «¿el documento 4186 es de quien lo está pidiendo?».

Cómo se cierra

$usuario = usuario_autenticado();
if (!$usuario) {
    return null;
}

return db()->fila(
    'SELECT * FROM documentos WHERE id = ? AND cliente_id = ?',
    [$id, $usuario->cliente_id]
);

La corrección no añade un control: quita la posibilidad de olvidarlo.

Mientras la autorización sea un if escrito al lado de la consulta, tarde o temprano alguien escribirá una consulta nueva sin ese if al lado — quizá dentro de dos años, quizá un proveedor distinto. Metida dentro de la consulta, la pregunta equivocada ya no se puede formular.

Y hay un efecto secundario útil: quien prueba un número al azar recibe un 404, así que ni siquiera aprende que ese número corresponde a algo.

Cómo se comprueba en el vuestro

Hace falta una persona que lo pruebe, con dos cuentas de prueba y media hora. Abrid algo con la primera cuenta, coged la dirección, y volved a probar con la segunda. Si veis el documento de la primera, lo habéis encontrado.

No hace falta ser técnico para hacer esta prueba. Solo hace falta hacerla.