v1.4.4
A security and correctness release. No new features, and nothing to do when upgrading.
🔒 Security
- The FreshRSS token can no longer leak to a third party. The proxy matched the server URL as a plain string prefix, so
server.tld.attacker.tldandserver.tld@attacker.tldboth passed. Image and favicon URLs come from feed content, so a hostile feed was enough. It now compares parsed origins. - Registration is closed by default. The first account is always allowed, so you are never locked out; reopen sign-ups in Preferences → Administration. Existing instances keep their current setting.
- The backend no longer runs as root. Node runs as
PUID/PGID— 1000 by default. The data directory is adopted on start, so no action is required. - Proxied requests are rate-limited per user. 600 per minute by default (
FRIRSS_PROXY_RATE_LIMIT,0disables). - Authentication is checked before the request body is read.
- Preference writes are bounded — key length, value size, keys per request, and total per user.
- Static assets now carry the security headers. This matters most for
.svg, which browsers treat as a document that can carry script. - Article extraction no longer stores markup wider than it displays. Only the videos the click-to-play facade understands survive.
- OIDC discovery goes through the anti-SSRF guard — the last outgoing call that used a bare
fetch(). - The development server's open proxy is gone. It relayed anywhere while forwarding every client header.
🐛 Fixes
- Mark all as read is no longer offered in Starred and Read Later. There, it marked the whole reading list and zeroed every counter.
- Unstarring no longer makes the row vanish. The list reconciles on reload, like every other view.
- Starring and Read Later are saved to the offline cache. Only read state was.
- Offline actions are no longer replayed twice when the network comes back.
🧹 Under the hood
- Dead code removed: the proxy's unused
X-Freshrss-Authfallback, an orphan CSS rule, two unused dev dependencies. SECURITY.mdnow documents a known limit of the anti-SSRF guard: it does not pin the address it validated, which leaves DNS rebinding open.- CI asserts that no application process runs as root, and that
/sw.jscarries neither a CSP norimmutable.
📖 Full history in CHANGELOG.md · 🐳 ghcr.io/fripix/frirss:1.4.4