Index: src/server.js
===================================================================
--- src/server.js	(revision 4fdbbe694783900c526dcdf005b186c6d970479c)
+++ src/server.js	(revision a9956989bad6c7bb7a8d1a6f506374070b001610)
@@ -250,5 +250,11 @@
   let originHost;
   try { originHost = new URL(origin).host; } catch { return res.status(403).send('Ongeldige origin'); }
-  if (originHost !== req.get('host')) return res.status(403).send('Cross-origin request geweigerd');
+  // Behind a reverse proxy the raw Host is the backend bind (e.g. localhost:3000, when the
+  // proxy doesn't preserve it — common with Apache .htaccess proxying), so also accept the
+  // operator-configured PUBLIC_BASE_URL host and the proxy's X-Forwarded-Host. Both are
+  // operator/proxy-controlled and can't be forged via a victim's browser, so this is safe.
+  const allowedHosts = [req.get('host'), req.get('x-forwarded-host')];
+  if (process.env.PUBLIC_BASE_URL) { try { allowedHosts.push(new URL(process.env.PUBLIC_BASE_URL).host); } catch { /* ignore bad config */ } }
+  if (!allowedHosts.includes(originHost)) return res.status(403).send('Cross-origin request geweigerd');
   next();
 });
