Booksy web-gateway — origin-validation bypass

Researcher k0nf · k0nf@intigriti.me · Intigriti — Booksy Bug Bounty
Served from — a domain not owned by Booksy.

Do this first — order matters

STEP 1. Log into Booksy Biz in this same browser (opens a new tab):

           → open Booksy Biz login

           Use the researcher's own test account. Credentials are in the Intigriti
           report, not on this page.

STEP 2. Come back to this tab and press ↻ Run again below.

Why: the session token only exists in the bridge's storage AFTER a login in this
browser. Running this page first, with no Booksy session, correctly finds nothing —
that proves the origin bypass but not the impact.

Result

waiting…

Environment

…

Every raw message received

(none yet)

Step-by-step log

⚠ Security research — not a Booksy service

notreallybooksy.com is NOT affiliated with, endorsed by or operated by Booksy.
Registered for ONE purpose: demonstrating a security issue to Booksy's security team
for a report filed through Intigriti.

  Researcher : k0nf        Contact : k0nf@intigriti.me
  Programme  : Intigriti — Booksy Bug Bounty (invite-only)

THIS SITE STORES NOTHING. IT IS PURELY READ-ONLY.
  - No session, token or identity is stored here. No database, no file, no log.
  - There is no backend. This is one static HTML file on a CDN.
  - Nothing is transmitted anywhere. Everything runs in YOUR browser and dies on reload.
  - No cookies, no localStorage, no analytics, no tracking, no third-party scripts.
  - The probes only READ. Nothing on Booksy's side is created or modified.

Only the researcher's own test account (k0nf-test-001@intigriti.me) on Booksy's
dedicated bug bounty TEST environment has been used. No real user, no production
system, no third party has been touched.

BOOKSY: this domain will be taken down immediately, or transferred to you free,
on request — no conditions. Email k0nf@intigriti.me.

The defect

https://web-gateway.bug-bounty.env.booksy.pm/assets/index.4cbdd068.js

  if (t.prod && !i.match(/booksy\.(com|net|pm)$/)) throw new Error("unauthorized domain");

`i` is event.origin. No start anchor, no leading dot -> it tests whether the origin
STRING ENDS WITH "booksy.com", not whether it IS a Booksy domain.

  https://booksy.com           -> accepted (intended)
  https://notreallybooksy.com  -> accepted (NOT intended)   <-- this page
  https://booksy.com.evil.net  -> rejected (correct)

Fix: /(^|\.)booksy\.(com|net|pm)$/  — or an explicit allowlist of exact origins.