Hacking Haircuts

Hacking Haircuts

How a salon booking system accidentally exposed thousands of client records

While using the check-in and booking system of a hairdresser chain that operates across most Australian states — I noticed some curious behavior in the site’s Existing Client feature.

Searching by first name brought up every “Mark” in the database (998 of us!). Even silly queries like entering an underscore for the last name returned every profile that used “_” as a surname — all 12,122 of them.

Not great, but since phone numbers and emails appeared to be masked, it didn’t seem too bad… at first.

Clicking Edit displayed the profile’s details again, with the phone number partially masked. However, checking the page source revealed that the full phone number was sent to the browser — it was only visually masked by JavaScript.
Even worse, the email field was simply hidden with CSS but still contained the unmasked address if one had been entered.

Back on the search page, unhiding all the hidden fields exposed an email search input — likely a forgotten remnant from an older version. Entering “@” or “.” into that field returned every profile with an email address: over 26,000 results for a single small store.

A quick Python proof-of-concept script confirmed that it was possible to search by email, common first and last names, or even single characters (a, b, 1, _, !, etc.). Each result conveniently included a UID for the user.

With a list of UIDs — and no rate limiting or CAPTCHAs in place — it became straightforward to fetch every profile’s data (since the “masked” data wasn’t actually masked) and save it into a local SQLite database.

The only obstacle was a cookie that expired every few hours, but simply changing the expiry date to something far in the future bypassed that. Later threaded versions of the script were so fast that the cookie issue didn’t matter anyway.

I reached out to the company through their online help form, and to their credit, they responded quickly and escalated the issue to their IT team. The vulnerabilities were patched within a few days.

Recommendations

  • Implement rate limiting or a CAPTCHA to deter automated scripts.
  • Require full phone number matching for client lookup.
  • Remove email search functionality entirely.
  • Limit the number of search results returned.
  • Never rely on JavaScript to mask data — and never send unmasked email or phone numbers to the browser.

My assumption is that this was an older system no one had revisited in a decade — it just worked.
Modern practices would have stopped me at several points. I can’t fault their response, and I’m confident everything’s secure now.