github ancsemi/Haven v3.43.0

latest releases: v4.29.0-beta.4, v4.29.0-beta.3, v4.28.0...
3 months ago

A security release. It covers both 3.42.0 and 3.43.0, since 3.42.0 was committed but never tagged.

Most of this exists because of a real incident on a Haven server: an account sat idle in voice channels for hours, then posted a link that auto-downloaded a file, was banned, came back and spammed the same link everywhere. Several things about how Haven worked made that easier than it should have been.

If you are upgrading, the protections below are switched on for you. Auto-mod, the domain allowlist, the 24-hour hold on links from new accounts and the image cache all default to on now. The two settings that can genuinely break something stay off until you choose them. If you turn any of it off, it stays off.


The short version

  • Haven fetches remote images itself and serves them from your server, so members' browsers never contact other sites
  • A configurable auto-mod with a domain allowlist, covering messages, edits, DMs, profiles and channel topics
  • IP bans actually work now; they had two defects that made them unreliable
  • Relay-only voice, which hides members' IP addresses during calls
  • Moderators with the ban permission can ban from the sidebar, and the "also ban IP" permission can finally be granted to a role

3.43.0

Haven loads images for your members now

This is the one worth understanding even if you skip everything else.

An image link in a message used to be loaded straight from wherever it was hosted, in every viewer's browser. That handed the owner of that link the IP address and browser details of everyone who scrolled past it. Nobody clicked anything. Nothing on screen suggested a request had been made.

Haven now fetches each image once, caches it on disk for 30 days, and serves it from your own server. It covers inline images, markdown images, link-preview thumbnails and revealed hidden images. A pleasant side effect, and the reason other chat platforms do the same, is that an embed keeps working after the original link expires or the host goes offline, so old conversations stop rotting.

You can see the cache size and turn it off under Settings → Security if bandwidth is tight. Thanks to @MutantRabbit767 for pushing on this.

Link-preview videos are not proxied, since relaying video needs range requests and a lot more bandwidth. Instead the poster comes from the cache and the video does not preload, so the remote host is only contacted if someone actually presses play.

Protections on by default

Auto-mod, allowlist link mode, the 24-hour new-account link hold and the image cache all default to on, for new installs and existing ones alike. Relay-only voice and automatic IP bans stay off, because the first needs a TURN server to work at all and the second can catch bystanders on shared connections.

Fixed

  • Moderators with the ban permission can ban from the sidebar. The ⛔ option in the member menu was gated on being an admin, even though the server has always accepted the ban_user permission. Moderators could ban from the admin members list but not from the sidebar they actually work in, which made it look like their permission was broken.
  • The "also ban IP" permission can be granted to a role. ban_ip was accepted by the server but missing from the role editor entirely, so there was no way to tick it for anyone. That made the IP-ban checkbox on the ban dialog admin-only in practice, regardless of what a moderator's role said.

3.42.0

Auto-Mod

A new section under Settings → Auto-Mod. Approve the domains people may link to and reject everything else the moment it is sent, so blocked content never reaches another client. It checks messages, edits, DMs, display names, status text, bios and channel topics, because a link parked in a profile reaches just as many people as one posted in a channel.

Resolving the real destination of a link is the part that decides whether any of this works, so it is done with a proper URL parser rather than pattern matching. https://youtube.com@evil.com/ really points at evil.com. https://evilyoutube.com/ is not a YouTube subdomain. A Cyrillic character dressed up as a Latin one is a different domain. Zero-width characters, hxxp://, evil[.]com and markdown links whose text disagrees with their target are all handled.

Twenty common domains are added to the allowlist on first run. The panel shows the most-blocked domains of the past week with one-click "allow", so anything caught by mistake is quick to fix.

Also included: warn, mute and ban escalation over a rolling window; an optional hold on links from brand-new accounts, which is the rule that breaks the register-post-get-banned-repeat loop without needing to recognise the link; and an optional mod-log channel.

Relay-only voice

Haven voice is peer to peer, which means that by default everyone in a call can see everyone else's IP address. That is simply how the connection gets made: no click, no prompt, no indication it happened. Sitting idle in a voice channel is enough to collect the address of anyone who joins.

Turning this on routes voice through your TURN server so participants only ever see the TURN server's address. It needs a TURN server configured first, and Haven will not let you enable it without one.

IP bans, fixed

  • They only half-applied. The web gate and the connection gate disagreed about what an address is: one saw 1.2.3.4, the other saw the same address in its IPv6 form. Banning someone blocked their web requests while their live connection carried on working.
  • Behind a reverse proxy they recorded the wrong address entirely. If Haven runs behind nginx, Cloudflare or similar, every connection was logged under the proxy's address rather than the visitor's. Ticking "also ban IP" would therefore have banned the proxy and locked out every user on the server.
  • Bans now accept CIDR ranges (203.0.113.0/24, 2001:db8::/64) and disconnect anyone already connected, including everyone inside a banned range. An IPv6 subscriber is normally handed a whole /64, so banning one of their addresses used to accomplish nothing.

Also fixed

  • The per-address connection limit did nothing behind a proxy, for the same reason as above: every visitor shared a single bucket.
  • Message rate limiting was counted per connection rather than per person. Two browser tabs bought twice the send rate, and reconnecting reset the limit outright.

Notes for admins

  • Restart your server to pick this up.
  • If your community shares links from sites outside the seeded allowlist, add them under Settings → Auto-Mod. The most-blocked list in that panel makes it obvious which ones people are actually trying to use.
  • The image cache lives in your data directory and is capped at 2 GB, evicting oldest first.
  • Two long-standing settings are worth turning on if you have not: a registration token and the Turnstile captcha, both under registration settings. Either one stops a banned account simply signing up again.

Don't miss a new Haven release

NewReleases is sending notifications on new releases.