github audreyt/ethercalc 0.20260611.1
0.20260611.1 — self-host hardening + security + storage bounds

latest release: 0.20260612.1
8 hours ago

Summary

Self-host hardening, security fixes, and per-room storage bounds — the biggest operational change since the April migration release. Docker and npm already ship this tag; this GitHub release catches the notes up.

Upgrade from 0.20260424.0? Room discovery (/_rooms*, /_exists) is now off by default on Docker/workerd/Helm. Rooms remain reachable by URL. For an internet-facing host, use the bundled nginx proxy recipe. See docs/SELFHOST_HARDENING.md.

Do not use the 0.20260611.0 image tag — it crashes under plain docker run with an anonymous volume. Use 0.20260611.1.

Self-host hardening

  • Room-index gate (SH-1). New ETHERCALC_DISABLE_ROOM_INDEX (default 1 on Docker/workerd/Helm) returns 403 on /_rooms, /_roomlinks, /_roomtimes, and /_exists. Legacy ETHERCALC_CORS honoured as fallback. CORS response headers stay permissive for embeds.
  • Nginx proxy recipe (SH-2). docker-compose.proxy.yml + deploy/nginx/ethercalc.conf — TLS-ready template, 25 MiB body limit, per-IP rate/conn limits, long WebSocket read timeouts.
  • Keyless warnings. Startup warns when ETHERCALC_KEY is unset and the listener is not loopback.
  • Non-root container (SH-8). Docker image drops to UID 1000 with read-only rootfs, caps dropped, seccomp; Helm chart 0.3.1 matches.
  • workerd binding fixes. Unset fromEnvironment bindings arrive as null (not '') — fixes GET //null redirect and room-index gate on bare workerd.
  • Anonymous-volume fix. Entrypoint chown keyed on /data/do so docker run with an anonymous volume no longer crashes workerd.

Security

  • Export + email surface (#830). CSV-injection defang, email CRLF strip, xlsx 200k-cell import cap, HTML-export CSP + nosniff.
  • Pre-prod hardening. H-4 cross-room rename restricted to the room's own <room>.<n> sub-sheet namespace; body limits; enum + email gates.
  • text/html XSS sanitization. DOMPurify hook in built static/socialcalc.js + HTMLRewriter on HTML export.

Reliability / storage

  • Log fold + DO storage bounds. Alarm-driven log fold into snapshot; ring buffer, chat/audit trim, per-room WS connection cap (128), per-frame byte cap (1 MiB).
  • Durable audit/chat D1 offload. Long-lived audit/chat mirrored beyond DO lifetime; self-healing tables.
  • Client reconnect fix. Prevents double-apply of commands on reconnect.
  • Cross-sheet refs. Hydrate double-quoted sibling refs ('other'!A1).

Docs / packaging

  • README: Cloudflare migration recipe, dated rollback extract, Ubuntu apt hint.
  • npm tarball fix: lean files manifest (2.2 MB packed vs 5 MB+), npm 11 bin path normalisation — npm artefact published from commit after this tag with identical runtime tree.

Install

npm install -g ethercalc@0.20260611.1
docker pull audreyt/ethercalc:0.20260611.1

Known self-host limitation (unchanged)

GET /_rooms returns [] on Docker self-host — the standalone workerd bundle doesn't wire D1, so cross-room enumeration is empty even when the gate is opened. Rooms remain accessible by URL.

Don't miss a new ethercalc release

NewReleases is sending notifications on new releases.