Security release for the 1.23 line. It backports three fixes from the 2.0 work; please upgrade. No migrations. Read the two upgrade notes below before upgrading.
Upgrade notes:
CALRS_TRUSTED_PROXIES(new). The rate limits now believeX-Forwarded-Foronly from a trusted proxy. By default calrs trusts loopback, private (RFC 1918), unique local and link-local addresses, so Caddy or Nginx on the same host or Docker network keeps working unchanged. If nothing sits in front of calrs, setCALRS_TRUSTED_PROXIES=none, otherwise clients on the LAN are trusted as proxies. Behind a proxy on a public address (load balancer, CDN), list its addresses or ranges, or every client is counted as the proxy. Behind a proxy with users on the LAN, list only the proxy's own address (CALRS_TRUSTED_PROXIES=127.0.0.1, or its Docker address). A range trusting everyone (0.0.0.0/0,::/0) is refused.calrs servelogs the list in force when it starts.- Calendar sources on a private IP literal need the allowlist. CalDAV and EWS sources, resource feeds and resource calendars are now checked at every request, not only when saved. This supersedes the 1.23.1 upgrade note, which said CalDAV and EWS sources were only checked when saved and so kept syncing: that is no longer true. One whose URL names a private or reserved IP address (for instance
http://10.0.0.5/orhttp://[fd12::1]/), or whose host name now resolves to one, stops syncing until it is on the private-host allowlist (CALRS_ALLOW_PRIVATE_HOSTSor Admin panel, System settings). List an address as the address itself, without brackets:CALRS_ALLOW_PRIVATE_HOSTS=fd12::1,10.0.0.5. Behind an outbound proxy (HTTPS_PROXY), make sure the proxy refuses internal destinations, or list internal calendar hosts inNO_PROXYso calrs checks them itself. The CLI now reads the allowlist and base URL stored in the database for every command, not onlyserve.
Security
- Rate limits trust
X-Forwarded-Foronly from trusted proxies - The per-address limits on sign-in, two-factor codes and bookings took the client's address fromX-Forwarded-Forwithout checking who sent the header. The address now comes from the connection; the header is read only when the connection comes from a trusted proxy, every line of it in order, right to left past the trusted hops, with ports dropped. A hop that is not an address puts the request in a bucket of its own, never the proxy's.X-Real-IPandForwardedare still ignored. IPv6 clients now count by their /64. - Outbound calendar requests connect only to addresses they checked (#363) - The private-address check on CalDAV, EWS and resource feed URLs and the request that followed it could see different addresses. These requests (CalDAV and EWS sources, Autodiscover, resource feeds and resource calendars,
calrs resource probe) now resolve the host at each connection, refuse it when any address is private or reserved unless the host is on the private-host allowlist, and connect only to the addresses they checked. Hosts a server names on its own, a CalDAV href on another host or a redirect, go through the same check, and private IP literals are checked against the allowlist at every request. A refused request stores a generic error on the sources page and in the owner's alert email and logs the address at warn level; the check when a URL is saved no longer shows the address a host name resolved to either. Allowlist entries that are IP addresses now match any spelling of the address (fd00:0::1andfd00::1). Calendar requests still honourHTTP_PROXY,HTTPS_PROXY,ALL_PROXYandNO_PROXY; a request through a proxy is resolved by the proxy, so filtering private addresses for it is the proxy's job, which calrs logs at startup, and a URL naming the proxy's own host is refused unless allowlisted. - The captcha verification and the meeting webhook no longer follow redirects - so the captcha secret and the signed webhook body only ever go to the configured host. The SMS gateways already followed none.