4dim / Notas
La cookie lleva token y firma, y hacen falta los dos
Meter todo dentro de la cookie te deja sin poder cerrar una sesión; guardar solo un identificador convierte una copia de tu base en sesiones abiertas de todo el mundo. Qué pierde cada atajo, y dónde vive el secreto.
Una cookie con dos mitades
Si tu aplicación guarda sesiones con una cookie, esta nota explica por qué hacen falta dos piezas y no una, y qué pierdes con cada una de las formas habituales de simplificarlo.
Nuestra cookie de sesión lleva dos cosas pegadas: un identificador al azar y una firma de ese identificador. Separadas por un punto.
Lo interesante no es el formato: es que cada mitad resuelve un problema que la otra no puede, y las dos formas de ahorrarse una son las dos formas habituales de hacerlo mal.
Sin firma, un identificador robado de la base bastaría. Sin identificador en la base, no habría forma de cerrar una sesión.
Si solo hubiera firma
La forma de moda es meterlo todo dentro de la cookie: quién eres y hasta cuándo vale, firmado para que no se pueda falsificar. No hace falta guardar nada en la base, y eso se vende como una ventaja.
Lo que pierdes es poder cerrar una sesión. Si esa cookie es válida por sí sola, sigue siéndolo hasta que caduque, pase lo que pase.
- Un empleado se va y quieres echarlo del sistema hoy.
- Alguien pierde el portátil con la sesión abierta.
- Un cliente sospecha que alguien entró y pide cerrar todo.
En los tres casos, la única respuesta es «espera a que caduque». No es aceptable, y la vuelta que suele darse —una lista de sesiones revocadas— consiste en volver a guardar en la base lo que se quería evitar guardar.
Si solo hubiera identificador
La forma opuesta es guardar en la cookie solo un identificador al azar, y buscarlo en la tabla de sesiones. Revocar es borrar una fila, que es justo lo que faltaba antes.
Lo que pierdes es la defensa contra una filtración de la propia base. Esos identificadores no son contraseñas: están guardados tal cual, porque hay que poder buscarlos. Quien consiga una copia de esa tabla —una copia de seguridad, un volcado para depurar— tiene sesiones abiertas de todo el mundo. Solo tiene que pegarlas en una cookie.
Con la firma, no. La firma se calcula con un secreto que vive en el entorno del proceso, no en la base. Una copia de la base no lleva ese secreto dentro, así que los identificadores filtrados no valen nada sin él.
| La cookie lleva | ¿Se puede revocar? | ¿Sirve una copia de la base? |
|---|---|---|
| Solo firma | No | No hay nada que copiar |
| Solo identificador | Sí | Sí: sesiones de todos |
| Las dos | Sí | No |
Comparar dos firmas sin contar el tiempo
Detalle pequeño con nombre raro: la comparación de la firma se hace en tiempo constante.
La comparación normal de dos textos se para en cuanto encuentra una diferencia. Eso significa que comparar dos firmas que empiezan igual tarda un poquito más que comparar dos que se diferencian en el primer carácter.
Ese «un poquito» se puede medir. Y midiéndolo muchas veces se puede adivinar una firma carácter a carácter, sin conocer el secreto. Es trabajoso, es real, y es fácil de evitar: hay una forma de comparar que tarda lo mismo pase lo que pase.
Antes de comparar se miran las longitudes, porque comparar longitudes distintas no tiene sentido y hay que descartarlo sin dar pistas.
La caducidad va en los dos sitios, y manda la base
La sesión dura ocho horas. Ese plazo aparece en dos lugares y conviene entender por qué no sobra ninguno.
En la cookie, para que el navegador la borre solo cuando pase. Es una cortesía con el usuario y no es una defensa: una cookie se puede conservar y volver a mandar.
En la consulta a la base, que solo acepta sesiones no caducadas. Esta sí es la defensa. Si solo estuviera la primera, una cookie guardada valdría para siempre.
La regla general: lo que decide tiene que comprobarse en el servidor. Todo lo que se le pide al navegador es una sugerencia que él cumple si quiere.
Por eso la cookie lleva además las tres banderas de siempre: que no se pueda leer desde el código de la página, que solo viaje por conexión cifrada, y que no se mande desde otros sitios. Las tres son una línea cada una y cierran tres ataques distintos.
Qué hacer entonces
- Comprueba si puedes cerrar la sesión de alguien ahora mismo.Si la respuesta es «cuando caduque», tu cookie no tiene la mitad que guarda estado.
- Pregúntate qué pasa si se filtra tu tabla de sesiones. Si eso da acceso, te falta la firma.
- Guarda el secreto de firma fuera de la base. En el entorno del proceso. Si vive en la misma base, no protege de nada.
- Compara firmas en tiempo constante. Es una función de la biblioteca estándar y una línea de código.
- Comprueba la caducidad en el servidor. La de la cookie es una cortesía, no una defensa.
Esta nota sale de nuestro trabajo en Desarrollo de Software a medida.