Pieza 11 de 64
Otra épocaPieza nº 0011 de 64

Una galleta que no se borraba

Hasta el 16 de septiembre de 2026, quien entraba en la web del Ministerio de Sanidad se llevaba, con la portada, un fichero de noventa líneas para manejar las cookies. Estaba escrito en español, las cookies eran galletas, y comentado paso a paso. Su función para borrar una galleta, si alguien la llamaba, paraba en seco el programa: lo ejecutamos para asegurarnos. Ese día, según el propio servidor, el fichero cambió y la función quedó arreglada.

Dominio
www.sanidad.gob.es
Guardado
31 AGO 2026
Comprobado en vivo
21 SEP 2026
Citas
7 en 2 ficheros guardados
Lectura
unos 4 min

Lo primero que llama la atención es que se entiende. Cada línea lleva su comentario en español explicando qué hace y por qué, la variable donde se vuelca el contenido de la cookie se llama galleta, y los comentarios conservan las erratas de quien los escribió con prisa: «si en la cookie estamo ya en nombre del valor», «devuleve el valor». El servidor lo daba por modificado por última vez el 14 de marzo de 2017, y así lo guardamos el 31 de agosto y lo volvimos a pedir el 15 de septiembre, idéntico.

Captura de https://www.sanidad.gob.es/
foto 1La cabecera de la portada del Ministerio de Sanidad el 23 de septiembre de 2026, sin pulsar nada; el aviso de cookies y la pestaña de accesibilidad están escondidos para que no la tapen. Es una de las catorce páginas que cargan el fichero de cookies de esta pieza, que desde el 16 de septiembre es la versión corregida. Lo que hace ese fichero no se ve en pantalla.Captura del 23 de septiembre de 2026, 14:18 (hora peninsular)
1de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 4 de 91
Copia
archivo
Guardado
31 ago 2026
Peso
2,6 kB
sha256
d2979066a147…
2function cojerValorCookie(indice) {
3    //indice indica el comienzo del valor
4    var galleta = document.cookie;
5    //busca el final del valor, dado por ;, a partir de indice
6    var finDeCadena = galleta.indexOf(";", indice);
7    //si no existe el ;, el final del valor lo marca la longitud total de la cookie
1El principio del fichero: la cookie del navegador, volcada en una variable llamada galleta.
2de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 25 de 91sigue en el mismo fichero · 21 líneas más abajo
22while (i < glen) {
23    var j = i + alen //posiciona j al final del nombre del valor
24    if (galleta.substring(i, j) == arg) //si en la cookie estamo ya en nombre del valor
25        return cojerValorCookie(j) //devuleve el valor, que esta a partir de j
26
27    i = galleta.indexOf(" ", i) + 1 //pasa al siguiente
28    if (i == 0)
2La búsqueda del valor dentro de la cookie, comentada línea a línea. Las erratas son del original.

La función que calcula cuándo caduca una galleta recibía un número de días y lo pasaba a milisegundos. Multiplicar por 24, por 60, por 60 y por 1.000 no tiene misterio. Lo tenía la orden que iba delante. Se llama eval y sirve para coger un texto y ejecutarlo como si fuera programa. Aquí se usaba para leer un número de días antes de multiplicarlo por veinticuatro, como quien pide a un intérprete que traduzca un número de teléfono.

3de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 45 de 91
Copia
archivo
Guardado
31 ago 2026
Peso
2,6 kB
sha256
d2979066a147…
43function caduca(dias) {
44    var hoy = new Date(); //coge la fecha actual
45    var msEnXDias = eval(dias)*24*60*60*1000; //pasa los dias a mseg.
46    hoy.setTime(hoy.getTime() + msEnXDias); //fecha de caducidad: actual + caducidad
47    return (hoy.toGMTString());
48}
3La cuenta de la caducidad, con un eval delante del número de días.

Lo comprobamos ejecutando el fichero tal como lo servía el ministerio. Si a esa función se le pedía que caducara en 90 días, contestaba con la fecha de dentro de noventa días, correctamente. Si se le pedía que caducara en “2*15”, un texto y no un número, contestaba con la de dentro de treinta. La multiplicación la hacía el eval, que ejecuta como programa el texto que le llegue, sea una cuenta o cualquier otra orden.

Unas líneas más abajo estaba la función que establece la galleta con su caducidad, y ahí convivían dos comentarios y un número. El comentario de arriba anunciaba noventa días de caducidad. El código pedía noventa días. Y el comentario de la derecha, en la misma línea, decía que la fecha se creaba para treinta y uno. No sabemos cuál de los dos sobrevivió a cuál. Sabemos que el que manda es el número, y que un lector desprevenido tenía una posibilidad entre dos de creerse el equivocado.

4de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 57 de 91
Copia
archivo
Guardado
31 ago 2026
Peso
2,6 kB
sha256
d2979066a147…
55function introducirCookie(parametro, valor) {
56    //establece la cookie, caducidad 90 días
57    var _dias = caduca(90); //crea la fecha de caducidad si 31 dias
58    if (valor != "")
59        guardarCookie(parametro, valor, _dias);
60}
4Dos comentarios y un número, en dos líneas seguidas: 90, 90 y 31.

Y llegamos al motivo de esta pieza. Para borrar una galleta, el truco de toda la vida es ponerle una fecha de caducidad del pasado: el navegador la tira. El comentario lo explicaba con esas palabras y el código lo hacía llamando a Caduca, con mayúscula, cuando la función que existe se llama caduca, con minúscula. JavaScript, el lenguaje en que está escrito el fichero, distingue mayúsculas. Para él son dos nombres distintos, y el segundo no existía.

5de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 52 de 91
Copia
archivo
Guardado
31 ago 2026
Peso
2,6 kB
sha256
d2979066a147…
50function borrarCookie(nombre) {
51    //para borrar la cookie, se le pone una fecha del pasado mediante Caduca(-1)
52    document.cookie = nombre + "=; expires=" + Caduca(-1) + "; path=/"
53}
54
55function introducirCookie(parametro, valor) {
5La función entera. El comentario nombra Caduca con mayúscula y el código también; la función que existe, dos párrafos más arriba, se llama caduca.

Cargamos el fichero en un navegador y pedimos borrar una galleta. La respuesta fue “ReferenceError: Caduca is not defined”, que es la manera que tiene JavaScript de decir que no sabe de quién le hablan. El programa se detiene ahí y la galleta se queda donde estaba, tan tranquila. Buscamos después esa palabra con mayúscula en todo lo que habíamos guardado del ministerio, por si alguien la definía en otro fichero y el asunto quedaba en un susto. No aparecía en ninguna parte.

Lo que salvaba al fichero era lo único que podía salvarlo: nadie llamaba a esa función. El resto sí se usaba, y guardarCookie y caduca se llaman desde otros ficheros del ministerio. En todo lo que guardamos no hay una sola línea que pida borrar una galleta. El error estaba ahí, como poco desde la fecha de marzo de 2017 que daba el servidor, esperando a un programador que un día decidiera usar la función que el fichero le ofrecía. Mientras tanto, Sanidad guardaba y renovaba sin problema.

Queda el detalle de las dos funciones con las que el fichero mete y saca el valor de la galleta, escape y unescape. Son de la primera época de JavaScript y desde 1999 la norma del lenguaje solo las conserva en el anexo de compatibilidad, con la recomendación expresa de no usarlas en código nuevo. Este no era nuevo: el 31 de agosto y el 15 de septiembre el servidor lo entregaba con la misma huella, los mismos finales de línea de Windows y los mismos 2.593 bytes. La versión corregida las sigue usando.

6de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 11 de 91
Copia
archivo
Guardado
31 ago 2026
Peso
2,6 kB
sha256
d2979066a147…
8    if (finDeCadena == -1)
9        finDeCadena = galleta.length;
10
11    return unescape(galleta.substring(indice, finDeCadena));
12    }
13
14function cojerCookie(nombre) {
6Una de las dos funciones que la norma del lenguaje dejó en el anexo de compatibilidad en 1999. La otra, escape, está en la línea que guarda el valor.

El 16 de septiembre de 2026 el fichero cambió. Lo dice el propio servidor, que desde entonces da esa fecha como la de su última modificación, y lo dicen las copias que volvimos a pedir el 21 y el 23. Donde estaba eval hay ahora Number, que convierte un texto en número sin ejecutarlo. borrarCookie llama a caduca con minúscula, en el código y en el comentario. El comentario de los treinta y un días ya no está, y el de los noventa ha perdido la í de «días» por el camino: dice «caducidad 90 d as». El resto, galleta y erratas incluidas, sigue igual.

7de 7www.sanidad.gob.es/diseno/js/cookie.jslínea 52 de 91
Copia
en vivo
Leído
21 sep 2026
Peso
2,6 kB
sha256
2aa99fd66fe2…
50function borrarCookie(nombre) {
51    //para borrar la cookie, se le pone una fecha del pasado mediante caduca(-1)
52    document.cookie = nombre + "=; expires=" + caduca(-1) + "; path=/"
53}
54
55function introducirCookie(parametro, valor) {
7El fichero desde el 16 de septiembre: Number donde estaba eval, y caduca con minúscula en el comentario y en el código.

Noventa líneas que lo explicaban todo y una mayúscula de más en el único sitio donde importaba. El 16 de septiembre se fue la mayúscula, y con ella una tilde.

Lo que decimos
  • El fichero cookie.js que servía www.sanidad.gob.es, con fecha de última modificación del 14 de marzo de 2017 e idéntico el 31 de agosto y el 15 de septiembre de 2026, calculaba la caducidad de sus cookies con eval, tenía en dos líneas seguidas dos comentarios y un número que no coincidían (90, 90 y 31) y su función borrarCookie llamaba a Caduca con mayúscula cuando la definida era caduca.
  • Ejecutado ese fichero tal cual, esa llamada devuelve “ReferenceError: Caduca is not defined”; en el archivo del ministerio no hay ninguna definición de Caduca ni ninguna llamada a borrarCookie fuera del propio fichero, aunque guardarCookie y caduca sí se llaman desde otros.
  • Lo cargan las 14 portadas guardadas (siete idiomas, dos direcciones cada uno).
  • El servidor da el 16 de septiembre de 2026 como fecha de la última modificación del fichero, y las copias del 21 y del 23 de septiembre llevan Number(dias) y caduca(-1), sin el comentario de los 31 días.
Lo que no decimos
  • No decimos que ninguna cookie del ministerio se quedara sin borrar en la práctica: la función rota no la llamaba nadie, y el aviso de cookies de la web puede estar manejado por otro programa que no hemos mirado.
  • No decimos que el eval de ese fichero fuera aprovechable por nadie: el número de días lo escribía el propio programa, no el visitante.
  • No decimos que el cambio del 16 de septiembre tenga que ver con esta pieza: no lo sabemos.
  • Y no hemos probado nada contra el servidor: descargamos el fichero, que es público, y lo ejecutamos en nuestro navegador.
Procedencia

De dónde sale cada cita

Cada trozo de código de esta ficha está en un fichero guardado tal como lo entregó el servidor, con su huella (sha256) y su hora. Las citas entre «» se comprueban por programa contra ese fichero antes de publicar.

El 21 de septiembre de 2026, 3 de sus 6 citas ya no aparecían en la página. Lo que ha cambiado desde que lo contamos.

Desgobierno Digital · https://desgobiernodigital.com/piezas/sanidad-galleta/ · copia impresa de la edición generada el 19 de octubre de 2026 · Un proyecto de BQuant · correcciones: @Gsnchez