LAFU Sales Reports

Crew website chat trusts a caller-supplied origin

BugShipped· 19 days ago

Imported from GitHub issue El-SaMa/oma#158 by @El-SaMa.


What is wrong

resolveWebsiteChatOrigin in apps/web/lib/crew/security.ts returns parentOrigin from the JSON body when the request has no Origin header, or when Origin is a portal host (oma.lanetti.fi, *.oma.lanetti.fi, localhost:3000).

The widget chat route (apps/web/app/api/crew/widget/[siteKey]/chat/route.ts) uses that value, and runWebsiteCrewChat checks it again with the same allow-list. The site key is public in the embed snippet. There is no signature that the request came from the customer site.

A caller can omit Origin and set parentOrigin to a site on that widget's allow-list. The chat then runs: Crew credits are spent, leads can be stored, and the reply is returned. No login is required.

Fix

Trust the browser Origin only. Do not accept parentOrigin from the body as proof of the visitor site. If the embed iframe must name its parent, sign that value (widget key or a short-lived token minted for the allowed origin) and reject anything else.

Found

Read-only review of origin/main, 8 Oct 2026. Not confirmed against the live server.

Comments (0)

No comments yet.

Join the discussion

Sign in to leave a comment on this thread.

HollahoopGet yours
Crew website chat trusts a caller-supplied origin · LAFU Sales Reports · Hollahoop