Skip to content

FileSync

v.4.0.0 Security

This release includes 2 security fixes for security teams reviewing exposed deployments.

Published 1mo File Storage & Sync
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 2 known CVEs

Topics

docker fastapi fileshare javascript self-hosted webrtc

Affected surfaces

auth breaking_upgrade

Summary

AI summary

Broad release touches Tooling & docs, Reliability, ✨ Highlights, and Connectivity.

Full changelog

A ground-up rebuild of how FileSync connects and saves files — native WebRTC, a built-in signaling server, and true streaming-to-disk for transfers of any size.

This is a major release. FileSync no longer depends on PeerJS: connection setup is now handled by a lightweight first-party signaling server bundled with the app, and received files stream straight to disk so even multi-gigabyte transfers stay memory-safe.

[!IMPORTANT]
Upgrading from 3.x requires re-downloading the compose files (docker-compose.yml, and for HTTPS the docker-compose-ssl.yml + Caddyfile). Pulling the new image alone is not enough — see Upgrading.


✨ Highlights

  • 🔗 Native WebRTC — PeerJS is gone. Smaller footprint, fewer moving parts, no third-party connection broker.
  • 📡 Built-in signaling server — served by FileSync itself at /ws. Nothing extra to run; it relays only connection setup and never sees your files.
  • 💾 Streaming downloads, any size — files are written to disk as they arrive, so memory stays flat even on multi-GB transfers.
  • 🩺 Redesigned diagnostics page at /test.html — light/dark, an at-a-glance verdict, and a one-click connectivity report to share with support.
  • 🛡️ Hardened for production — required secret at startup, rate-limited credentials, a self-healing container, and self-hosted fonts.

🚀 What's new

Connectivity

  • Native RTCPeerConnection / RTCDataChannel client replacing the PeerJS wrapper.
  • First-party WebSocket signaling relay (/ws) with rate limiting, idle timeouts, and capacity guards.
  • Relayed transfers now work correctly behind Docker — TURN relay candidates are rewritten in transit so peers on different networks get a reachable address.

Transfers

  • Chunked, backpressured protocol that keeps both sender and receiver memory bounded.
  • Three save methods, auto-selected per browser:
    | Method | When | Notes |
    |---|---|---|
    | File System Access | Desktop Chrome/Edge/Brave/Opera (HTTPS) | Streams straight to a file you pick |
    | Service Worker | All modern browsers (HTTPS) | Streamed browser download, memory-safe |
    | Blob | Fallback / plain HTTP | Buffered in memory (~500 MB practical limit) |

Reliability

  • Serialized disk writes — fixes a File System Access corruption case on fast/large transfers.
  • Transfers no longer hang if a peer drops mid-send; abort, remove, and "cancel all" now tear down cleanly (no leaked connections or stuck downloads).
  • Transient network blips are tolerated instead of killing an in-progress transfer.
  • The container self-heals: if the backend process dies, it restarts instead of serving a half-dead app.

Security

  • The server refuses to start without SECRET_KEY (used to sign TURN credentials and tokens).
  • /api/credentials is rate-limited; CORS is off by default (opt-in via CORS_ORIGINS).
  • Fonts are self-hosted — no third-party font CDN, satisfying the app's strict Content-Security-Policy.

Tooling & docs

  • End-to-end Playwright test harness covering browsers × save methods × connection modes.
  • Dependabot for Python, Docker, GitHub Actions, and the test harness.
  • README refreshed: how connections are made, the required ports, and how files are saved.

⚠️ Upgrading from 3.x

The compose files changed — re-download them.

  1. Re-download the deploy file(s) for your setup:

  2. Set your secret (now required — the app won't start without it). Generate one:

    python3 -c "import secrets, base64; print(base64.b64encode(secrets.token_bytes(32)).decode())"
    

    Replace both <SECRET_KEY> placeholders in the compose file.

  3. Open the required ports (below) if you haven't already.

  4. Pull and restart:

    docker compose pull && docker compose up -d
    

💡 No separate PeerJS server is needed anymore — if you ran one, you can decommission it.


📋 Required ports

| Port | Protocol | Purpose |
|---|---|---|
| 80 / 443 | TCP | Web interface (HTTP / HTTPS) |
| 3478 | TCP + UDP | STUN/TURN — connection setup |
| 50000–50100 | UDP | TURN relay range (used when a direct path isn't possible) |


Full changelog: https://github.com/polius/filesync/compare/v.3.7.0...v.4.0.0

Breaking Changes

  • PeerJS dependency removed; native WebRTC (`RTCPeerConnection`/`RTCDataChannel`) replaces it.
  • Required `SECRET_KEY` environment variable at startup – the server refuses to start without it.
  • Compose files changed: re‑download `docker-compose.yml`, `docker-compose-ssl.yml`, and `Caddyfile` for upgrade; pulling only the new image is insufficient.

Security Fixes

  • Server requires `SECRET_KEY` for TURN credential signing; without it the process aborts (prevents unauthenticated access).
  • Rate‑limited `/api/credentials`, CORS disabled by default (`CORS_ORIGINS` opt‑in), and self‑hosted fonts enforce strict CSP.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track FileSync

Get notified when new releases ship.

Sign up free

About FileSync

Send files from one device to many in real-time.

All releases →

Related context

Beta — feedback welcome: [email protected]