Pieza 28 de 64
AccesoPieza nº 0028 de 64

Cuatrocientas sesenta y tres líneas para un cero

Quien se da de alta en la Plataforma de Contratación del Sector Público elige una contraseña, y a su lado hay un contador que empieza en 0. La página está programada para subirlo hasta 100 mientras se escribe, y pide llegar a 60. Ese número lo calcula en el navegador un fichero de 463 líneas. El formulario guarda aparte, escondido, otro número para mandar al servidor, y mientras se teclea nadie lo toca: se queda en el cero con que llega.

Dominio
contrataciondelestado.es
Guardado
05 SEP 2026
Citas
7 en 2 ficheros guardados
Lectura
unos 4 min
Captura de https://contrataciondelestado.es/
foto 1La portada de contrataciondelestado.es el 23 de septiembre de 2026: la Plataforma de Contratación del Sector Público.Captura del 23 de septiembre de 2026, 10:17 (hora peninsular)

El formulario es de los completos: usuario, correo, contraseña, repetir contraseña, un captcha y un aviso de seguridad que hay que aceptar. A la derecha de la contraseña hay un contador rotulado Complejidad de la contraseña, que empieza en cero. Debajo, las reglas: de 8 a 30 caracteres, ni eñes ni acentos, y un grado de complejidad de al menos 60. Y dos botones, Mostrar contraseña y Generar contraseña.

Captura de https://contrataciondelestado.es/wps/portal/registrarse
foto 2La página de alta de la Plataforma de Contratación el 26 de septiembre de 2026, tal como se abre. El recuadro es nuestro y señala el rótulo Complejidad de la contraseña; a su derecha, el contador, en 0 porque nadie ha escrito nada. Debajo, las reglas, y a la izquierda los botones Mostrar contraseña y Generar contraseña. El campo escondido que viaja con el alta no se ve.Captura del 26 de septiembre de 2026, 15:43 (hora peninsular) · el recuadro es nuestro

Ese contador lo calcula un fichero llamado calculadorFortalezaContrasenya.js, de 16.591 bytes y 463 líneas de JavaScript, el lenguaje de los programas que corren en el navegador. Y se ejecuta entero en cada tecla: los dos campos, el de la contraseña y el de repetirla, lo llaman con cada pulsación, y la cuenta se rehace con la contraseña completa cada vez. Doce caracteres son doce vueltas al fichero, con sus bucles y sus expresiones regulares, los patrones con que se busca una forma dentro de un texto. No se nota, pero está pasando.

1de 7contrataciondelestado.es/wps/PA_PortletsPlace/js/fuerzaContrasenya/calculadorFortalezaContrasenya.jslínea 120 de 464
Copia
archivo
Guardado
5 sep 2026
Peso
16,6 kB
sha256
21f98d34fe83…
117/******************************************************************************************************************
118Funcion principal que comprueba la fortaleza de una contraseña.
119******************************************************************************************************************/
120function comprobarFortalezaPassword(pwd,idUsuario,minLongitudPassword,maxLongitudPassword,minFortalezaPassword,caracteresEspeciales){
121    
122    var oScorebar = $("scorebar");
123    var oScore = $("score");
1La función principal del calculador. La llaman los dos campos de contraseña en cada tecla, con la contraseña entera.

Lo que hace dentro tiene su mérito. Cuenta mayúsculas, minúsculas, números y símbolos. Detecta caracteres repetidos y penaliza. Detecta secuencias, tres letras, tres números o tres símbolos seguidos, y penaliza otra vez. Comprueba que la contraseña no sea un NIF, con un patrón de siete o más cifras y una letra mayúscula. Comprueba que no contenga el nombre de usuario. Suma, resta, y al final deja el resultado entre 0 y 100.

2de 7contrataciondelestado.es/wps/PA_PortletsPlace/js/fuerzaContrasenya/calculadorFortalezaContrasenya.jslínea 5 de 464
Copia
archivo
Guardado
5 sep 2026
Peso
16,6 kB
sha256
21f98d34fe83…
2Funcion para corregir que el algoritmo para que la calidad de contraseñas compuestas por una serie de números
3y una letra mayúscula (p.e. un NIF) no supere el umbral (en contra de las condiciones de calidad).
4******************************************************************************************************************/
5function comprobarSiNIF(password){
6    var esNIF=false;
7    
8    var expresion_regular_nif = /^\d{7,}[A-Z]$/;
2Una de las comprobaciones: que la contraseña no sea un NIF, siete o más cifras y una letra mayúscula.

Por el camino se fabrica una herramienta que el lenguaje ya traía: una función para dar la vuelta a un texto, escrita a mano, carácter a carácter, y añadida a todos los textos del programa. JavaScript sabe hacerlo en una línea. Aquí ocupa nueve, y se usa tres veces, para buscar las secuencias también del revés. Nada de eso es un fallo: un contador en el navegador es lo que hay que hacer, porque su trabajo es avisar a quien teclea, ahí mismo y sin esperas. Lo curioso está en la página que lo carga.

3de 7contrataciondelestado.es/wps/PA_PortletsPlace/js/fuerzaContrasenya/calculadorFortalezaContrasenya.jslínea 107 de 464
Copia
archivo
Guardado
5 sep 2026
Peso
16,6 kB
sha256
21f98d34fe83…
104/******************************************************************************************************************
105Funcion que devuelve una cadena al revés.
106******************************************************************************************************************/
107String.prototype.strReverse = function() {
108    var newstring = "";
109    
110    for (var s=0; s < this.length; s++) {
3Dar la vuelta a un texto, escrito a mano y añadido a todos los textos del programa. El lenguaje ya sabía hacerlo.

Dentro del formulario hay un campo escondido, de los que no se ven en pantalla y viajan igual cuando uno pulsa el botón de enviar. Se llama idFuerzaContrasenyaAutoRegistro, algo así como fuerza de la contraseña del alta, y llega con el valor 0. O sea que, además de enseñarle el número a quien se registra, la página tiene preparado un sitio para mandárselo al servidor, el ordenador de la Plataforma que recibe el alta.

4de 7contrataciondelestado.es/wps/portal/registrarselínea 934 de 1.341
Copia
archivo
Guardado
5 sep 2026
Peso
77,3 kB
sha256
2b4d3a605c92…
931    <div class="btn-group right">
932        <script type="text/javascript" src="/wps/portal/plataforma/buscadores/busqueda/!ut/p/z1/hY5LT4NAFIV_DUvnDq9Kl7QgYNqUPpHZkAuOFcMwyCv6752-Fk00Lk_Ouff7gEH6YOi6rRuWPXXgBViNY3nEvpQ1ViqnbJJZ_mo-fwoN6mxNjxoLb7-fhCoGNqRq8Ji5B3_tRlOTrmYbNXiOl7s4MHRKLdgCA1ZIQcp…
933        <!-- Enlace para generar nueva contrase&#241;a -->
934…value="0" />
935    </div>
936</div>
937<div class="row no-gutters">
4El campo escondido que viaja con el alta, con el valor con que llega la página.

Quien lo rellena es una función, escribirFortaleza, que pinta la barra, escribe el número en pantalla y, si el campo escondido existe, le mete el valor. Es la única línea de la página que escribe ese campo. Y a esa función solo la llama un sitio: la respuesta de una petición al servidor que devuelve la palabra FORTALEZA y un número. El número que viaja lo calcula el servidor, y el navegador lo copia.

5de 7contrataciondelestado.es/wps/portal/registrarselínea 812 de 1.341
Copia
archivo
Guardado
5 sep 2026
Peso
77,3 kB
sha256
2b4d3a605c92…
809    oScore.innerHTML = fortaleza;
810    
811    if(document.getElementById("viewns_Z7_GG0I1BG0416JC06P6I19DM1006_:form1:idFuerzaContrasenyaAutoRegistro")){
812        document.getElementById("viewns_Z7_GG0I1BG0416JC06P6I19DM1006_:form1:idFuerzaContrasenyaAutoRegistro").value = fortaleza;
813    }
814}
5La única línea de toda la página que escribe ese campo. Vive dentro de escribirFortaleza, y a escribirFortaleza solo la llama la respuesta del servidor.

Falta saber cuándo se le pregunta al servidor. La petición vive en una función llamada calculoFortalezaAjax, y la página la llama una sola vez, dentro de un if, una condición: solo si la variable copiarContrasenyas es verdadera. Dos líneas más arriba, en el mismo bloque, la página trae escrito su valor: false. Así que, en la página tal como se abre, esa pregunta no se hace, y teclear la contraseña no la dispara.

6de 7contrataciondelestado.es/wps/portal/registrarselínea 1131 de 1.341
Copia
archivo
Guardado
5 sep 2026
Peso
77,3 kB
sha256
2b4d3a605c92…
1130<script type="text/javascript">
1131    var copiarContrasenyas = false;
1132    
1133    if(copiarContrasenyas){
1134        if(document.getElementById("viewns_Z7_GG0I1BG0416JC06P6I19DM1006_:form1:secret1")){
6Y la condición que decide si se le pregunta al servidor: en la página recién abierta, false, dos líneas antes de usarse.

Lo que no sabemos es si esa variable vale siempre false. Está escrita en la página que manda el servidor, y en todas las copias que tenemos, que son de la página recién abierta, vale false. El botón Generar contraseña envía el formulario al servidor, que devuelve la página otra vez. Qué trae entonces esa variable, cuyo nombre habla de copiar contraseñas, no lo hemos visto, porque el museo no envía formularios de nadie.

Lo escrito es esto. Mientras alguien teclea su contraseña en la página recién abierta, el contador de la pantalla sube y baja con las 463 líneas del navegador, y el campo escondido no se entera: sigue en el cero con que llegó. La cuenta que la página tenía prevista para el servidor tiene su dirección escrita ahí arriba, la de un servlet, un programa del servidor que contesta peticiones, llamado CalculoFortalezaPasswordAjaxServlet. Esa pregunta no se hace.

7de 7contrataciondelestado.es/wps/portal/registrarselínea 763 de 1.341
Copia
archivo
Guardado
5 sep 2026
Peso
77,3 kB
sha256
2b4d3a605c92…
760    var minFortPass = 60;
761    var caracEspec = '._-+*!@#$%&/()=?&#191;[]{}';
762
763    var urlPeticionAjax = "/wps/PA_PortletsPlace/servlet/CalculoFortalezaPasswordAjaxServlet";
764    
765function beforeSubmit(){
7La dirección del cálculo que haría el servidor, escrita en la página. En la página recién abierta, nadie la llama.

Qué hace el servidor con ese cero cuando le llega el alta no lo sabemos, y no vamos a averiguarlo: habría que enviar el formulario. Puede que lo ignore y haga su propia comprobación. Lo que se puede afirmar es lo que está en la página: el número que prepara para mandar no cambia al teclear, y lo que calculan las 463 líneas a cada tecla se queda en la pantalla.

Y sigue igual. El fichero que pedimos el 15 y el 26 de septiembre de 2026 tiene la misma huella y los mismos 16.591 bytes que el que guardamos el 4. La página conserva la variable en false, el campo escondido con su cero y las cuatro llamadas al calculador, dos por campo. La copia del 4 se sirvió en inglés y la del 26, en español: las mismas líneas, palabra por palabra.

La página calcula un número a cada tecla y lo enseña. El que tiene preparado para mandar, mientras se teclea, es el cero con el que llegó.

Lo que decimos
  • En la página de alta de contrataciondelestado.es, guardada el 4 de septiembre de 2026, los dos campos de contraseña llaman en cada pulsación a comprobarFortalezaPassword, una función del fichero calculadorFortalezaContrasenya.js, de 463 líneas y 16.591 bytes, que calcula un número de 0 a 100 y lo escribe en pantalla.
  • El formulario incluye un campo oculto llamado idFuerzaContrasenyaAutoRegistro con valor 0.
  • La única línea de la página que asigna ese campo está dentro de la función escribirFortaleza, a la que solo llama la respuesta de calculoFortalezaAjax; y calculoFortalezaAjax se invoca una sola vez, dentro de un if cuya condición es la variable copiarContrasenyas, declarada dos líneas antes con valor false en la página tal como se sirve al abrirla.
  • En el calculador, la función que da la vuelta a un texto ocupa nueve líneas y se usa tres veces, y el patrón del NIF es de siete o más cifras y una letra mayúscula.
  • El 15 de septiembre de 2026, pedida en español y en inglés, y el 26, pedida en español, la página conserva las mismas líneas y el fichero tiene el mismo sha256.
Lo que no decimos
  • No decimos qué hace el servidor con ese cero cuando recibe el alta: no lo hemos comprobado y no vamos a hacerlo, porque eso exigiría enviar un formulario, y el museo solo lee.
  • No decimos que copiarContrasenyas valga siempre false: vale false en la página recién abierta, y no sabemos qué vale cuando el servidor la devuelve después de Generar contraseña.
  • No decimos que una contraseña débil se acepte, ni que una fuerte se rechace.
  • No decimos que el calculador esté mal hecho; hace lo que dice.
  • Y no decimos nada de la dirección del servlet más allá de que está escrita en la página.
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.

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