Skip to content

sec+docs: endurecer contenedor y cabeceras, licencia Apache 2.0 y protocolo de relay documentado - #53

Merged
Oloxx merged 3 commits into
mainfrom
sec/cabeceras-licencia-y-protocolo
Sep 11, 2026
Merged

sec+docs: endurecer contenedor y cabeceras, licencia Apache 2.0 y protocolo de relay documentado#53
Oloxx merged 3 commits into
mainfrom
sec/cabeceras-licencia-y-protocolo

Conversation

@Oloxx

@Oloxx Oloxx commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Las tres P2 que quedaban sin depender de tocar el protocolo de transferencia.

Contenedor y cabeceras (#30)

El contenedor corría como root: node:22-alpine ya trae un usuario node sin privilegios
que no se estaba usando. Y no declaraba HEALTHCHECK pese a que /healthz existe desde el
principio, así que Docker sabía si el proceso seguía vivo, no si seguía sirviendo. Se pregunta
con el propio Node, que no hay curl en la imagen.

Las respuestas llevan ahora CSP, X-Content-Type-Options, Referrer-Policy y
Permissions-Policy:

default-src 'self'; script-src 'self'; style-src 'self'; font-src 'self';
img-src 'self' data:; media-src 'self' blob:; connect-src 'self';
object-src 'none'; base-uri 'self'; form-action 'none'; frame-ancestors 'none'

Van en server/index.js y no en el Caddyfile a propósito: así viajan con la aplicación —valen
igual en npm run dev, en la suite y en un despliegue sin Caddy— y sobre todo se pueden
probar
, en vez de confiar en que el proxy de producción esté bien. HSTS es la excepción y
se queda en Caddy: anunciarlo desde un servidor que también habla http dejaría inaccesible el
localhost de quien desarrolle, durante meses.

Sin 'unsafe-inline' ni 'unsafe-eval', que es lo que hace que la política valga algo. Eso
obligó a quitar el único estilo en línea que quedaba, un style="color: var(--red)" en
index.html que el navegador estaba bloqueando.

Licencia y documentos del repo (#31)

El repositorio es público y distribuye binarios para cinco plataformas sin licencia
declarada
, que por defecto significa que nadie tiene permiso legal para usarlo, modificarlo ni
redistribuirlo. Ahora es Apache 2.0: permisiva como MIT, pero con concesión expresa de
patentes y obligación de indicar los cambios.

  • CONTRIBUTING.md recoge lo que había que deducir leyendo el código: entorno, tests,
    comentarios que explican el porqué, formato de commits, interfaz en inglés y resto en español,
    y cero peticiones a terceros.
  • CHANGELOG.md reconstruye las diecisiete versiones publicadas desde los tags y las notas de
    cada release.
  • license, author y repository en el package.json.

El protocolo de relay, en un solo sitio (#32)

Los mensajes cli-* estaban repartidos entre tres ficheros sin descripción central. No es un
problema estético: tres implementaciones parciales del mismo protocolo es exactamente lo que
dejó al receptor sin mandar los acuses que el emisor espera, parando cualquier transferencia al
llegar a la ventana de 8 MB.

La descripción canónica va encima de receiveFromRelay en cli/src/transfer.js —cada mensaje,
quién lo emite, cuándo y qué espera de vuelta, con el control de flujo por ventana de acuses y
el reloj de inactividad—, y las otras dos implementaciones apuntan ahí.

Verificación

  • npm test: 107/107, con tres casos nuevos en test/headers.test.mjs. Uno de ellos falla
    si alguien vuelve a meter un style=, un <script> sin src o un on*= en public/*.html,
    que es la forma habitual de acabar aflojando la CSP hasta dejarla en adorno.
  • Chrome de verdad: cero violaciones de CSP en / y en /speed, consola limpia.
  • Transferencia completa de 8 MB entre dos pestañas bajo la CSP, y la cadena de reenvío con dos
    receptores (1,05 copias, los dos con el hash correcto).
  • El USER node y el HEALTHCHECK no se pueden probar aquí (no hay Docker en esta máquina): se
    verán en el despliegue, y lo confirmaré con docker compose ps en el VPS.

Closes #30, closes #31, closes #32.

El contenedor corria como root: la imagen node:22-alpine trae un usuario `node`
sin privilegios que no se estaba usando. Y no declaraba HEALTHCHECK pese a que
/healthz existe desde el principio, asi que Docker solo sabia si el proceso
seguia vivo, no si seguia sirviendo. Se pregunta con el propio Node, que no hay
curl en la imagen.

Las respuestas llevan ahora CSP, X-Content-Type-Options, Referrer-Policy y
Permissions-Policy. Van en server/index.js y no en el Caddyfile para que viajen
con la aplicacion -- valen igual en `npm run dev`, en la suite y en un despliegue
sin Caddy -- y sobre todo para poder probarlas. HSTS es la excepcion y se queda
en Caddy: anunciarlo desde un servidor que tambien habla http dejaria
inaccesible el localhost de quien desarrolle, durante meses.

La CSP esta ajustada a lo que la web usa de verdad: ni 'unsafe-inline' ni
'unsafe-eval', y ni una peticion a terceros (la fuente ya estaba servida desde
public/fonts). Eso obligo a quitar el unico estilo en linea que quedaba, un
style="color: var(--red)" en index.html que el navegador bloqueaba.

Verificado con Chrome de verdad: cero violaciones de CSP en / y en /speed, una
transferencia completa entre dos pestanas y la cadena de reenvio con dos
receptores, las dos con el hash comprobado.

Cierra #30.
El repositorio es publico y distribuye binarios para cinco plataformas sin
licencia declarada, que por defecto significa que nadie tiene permiso para
usarlo, modificarlo ni redistribuirlo: justo lo contrario de lo que pretende el
proyecto. Se elige Apache 2.0 -- permisiva como MIT, pero con concesion expresa
de patentes y obligacion de indicar los cambios.

CONTRIBUTING recoge lo que hasta ahora habia que deducir leyendo el codigo: como
montar el entorno, que los tests ya no necesitan servidor, que los comentarios
explican el porque y no el que, el formato de los commits, que la interfaz va en
ingles y todo lo demas en espanol, y que la web no hace ni una peticion a
terceros.

CHANGELOG reconstruye las diecisiete versiones publicadas a partir de los tags y
de las notas de cada release.

Cierra #31.
Los mensajes `cli-*` estaban repartidos entre cli/src/cli.js, cli/src/transfer.js
y public/app.js sin ninguna descripcion central: tres implementaciones parciales
del mismo protocolo, y las divergencias entre ellas son exactamente lo que dejo
al receptor sin mandar los acuses que el emisor esperaba, parando cualquier
transferencia al llegar a la ventana de 8 MB.

La descripcion canonica va encima de `receiveFromRelay`, en transfer.js: cada
mensaje, quien lo emite, cuando y que espera de vuelta, incluido el control de
flujo por ventana de acuses y el reloj de inactividad. Las otras dos
implementaciones apuntan ahi.

Cierra #32.
@Oloxx
Oloxx merged commit 16f213a into main Sep 11, 2026
3 checks passed
@Oloxx
Oloxx deleted the sec/cabeceras-licencia-y-protocolo branch September 11, 2026 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: documentar el protocolo de relay del CLI en un solo sitio docs: LICENSE, CONTRIBUTING y CHANGELOG ops: endurecer el contenedor y el proxy

1 participant