img

The Ghost in the Machine

Investigating a Shopify Scareware Redirect When the Evidence Was Already Gone

Platform Shopify
Threat Type Mac-targeting scareware redirect
Outcome Site secured; root cause unconfirmed
Key Challenge Primary evidence removed before investigation began

The Call

The client ran a small meal subscription business on Shopify. His friend had been browsing the store when something alarming happened: he was suddenly redirected to a page displaying a fake “MacOS Security Center” alert, claiming his system was under threat and urging immediate action.

The scareware page was hosted on landr-atlas.com. My initial threat intelligence showed it had an 80/100 threat score on Hybrid Analysis, had been registered just weeks earlier with hidden WHOIS information, and was flagged by Google Safe Browsing. The domain exhibited sandbox evasion behavior—analysis environments got blank pages while real users got the attack.

By the time the client reached out to me, he’d already taken what seemed like the obvious remediation step: he’d uninstalled Tidio, a live chat application that had been installed just days before the incident. He’d also revoked collaborator access from an Upwork developer who’d been configuring it.

The crime scene had been cleaned before I arrived.


Adapting to a Hosted Platform

Shopify presents a different challenge than self-hosted platforms like WordPress. There’s no server access, no file system to grep through, no database to query, no access logs to review. The core platform files are immutable. This constrains the attack surface considerably, but it also shifts where malicious code can hide: theme files, apps, the Script Tags API, custom pixels, third-party integrations, and metafield-driven dynamic loading.

I would need to approach this methodically, ruling out vectors one by one while working within the platform’s constraints.


First Theory: The Timeline Points to Tidio

I started with the store’s activity log and found something that seemed significant: Tidio was the only app or configuration change between September 2025 and the incident in January 2026. A three-month gap of complete inactivity, then Tidio installed December 30th, the redirect reported January 3rd, Tidio removed the same day.

The timeline correlation was compelling. But Tidio was gone, and I couldn’t examine it directly.

I turned to the theme files. I ran comprehensive searches across the exported theme for indicators of compromise: the malicious domain, obfuscation patterns like eval() and atob() and fromCharCode(), base64-encoded payloads, Mac fingerprinting code, redirect logic. I compared the current live theme against the oldest backup in the library.

Everything came back clean.


Second Theory: The Polyfill.io Smoking Gun

Then I found something that made my heart rate spike.

Buried in the theme’s snippets/booster-apps-common.liquid file was a reference to polyfill.io—a domain that had been compromised in February 2024 when it was sold to a company called Funnull. After the acquisition, the domain began serving conditional malware: Mac and mobile targeting, scareware redirects, fingerprinting to evade security tools. The attack profile matched our symptoms perfectly.

I had my answer. Or so I thought.

Further analysis revealed the polyfill.io domain was no longer operational—it returned no content. A dead domain can’t serve malicious payloads. The live homepage was actually using polyfill-fastly.net, a safe alternative hosted by Fastly. The booster-apps-common snippet containing the old reference wasn’t even loading on the homepage.

Polyfill.io was a red herring. Back to Tidio.


The Situation Changes

While I was analyzing network traffic and categorizing every external script loading on the site—jQuery from Google APIs, carousel libraries from Cloudflare’s CDN, Klaviyo for email marketing, Judge.me for reviews, all legitimate—the client sent an update that changed everything:

“I just had my friend pull it up and it is still popping up.”

The redirect was still happening. Removing Tidio hadn’t fixed it.

This meant either Tidio was never the cause (and the timeline correlation was coincidental), or something else was persisting independently. Polyfill.io was back on the table—except I’d already ruled it out. I was chasing ghosts.


Trying to See What the Victim Saw

The attack appeared to use sophisticated fingerprinting. Based on the available evidence, it seemed to profile visitors and serve malicious content only to specific user profiles while showing clean pages to everyone else.

I attempted reproduction from multiple angles. I tried user-agent spoofing from my Linux system. Simply changing the User-Agent header wasn’t enough though if the attack was fingerprinting visitors, it was likely checking navigator.platform, WebGL renderer information, canvas fingerprinting, and possibly IP reputation databases that distinguish residential connections from datacenter or VPN traffic. I tested from an iPhone. I tested from an iPad. I tested from a Mac. Nothing. The site loaded cleanly every time.

The client had multiple other people try from Macs. No one could trigger it. Why could the client’s friend?


The Witness Gets Burned

While helping us test, the client’s friend opened the site in an incognito window. The redirect happened. And then, in the confusion of the moment while analyzing the network tab in devtools, he accidentally clicked something on the scareware page.

His Mac was now compromised. A browser hijacker had been installed. Typing the store’s name into his browser now redirected him to malicious pages regardless of what the actual website was serving.

The client was shaken. His friend’s computer was infected, and we still didn’t know what was causing it.

From an investigative standpoint, I’d lost my only witness who could reproduce the issue. Any testing from his device was now unreliable because his local malware would interfere with results. I couldn’t distinguish between “the site is still infected” and “the friend’s browser is hijacked.”

The forensic opportunity was gone.


Back to Tidio—One More Time

The client still had access to his Tidio account, so I investigated there. I reviewed the single active flow: a standard “Proactive Welcome Message” template. First visit trigger, chat status check, send appropriate greeting. No JavaScript execution actions, no redirect logic, no custom code.

I analyzed Tidio’s actual widget JavaScript—the minified code that loads from their CDN. I searched for the same malicious patterns: eval(), obfuscation, suspicious domains, fingerprinting, redirects. I found only legitimate components: Sentry error tracking, standard chat API methods, iframe creation, font preloading, WebSocket connections to Tidio’s servers.

The Tidio code was clean. More importantly, the Last-Modified header on their widget iframe chunk showed December 30th—the same day it was installed, before the attack was reported. The code hadn’t changed between installation and the incident.

I looked for login history or security audit logs in Tidio’s dashboard. They don’t exist. Tidio doesn’t expose this to users.


The Cached Code Theory

A new possibility emerged: what if the friend’s browser had cached a version of the site from when malicious code was present? If Tidio—or something injected through Tidio—had briefly served malicious content, the friend’s browser might have held onto it even after the code was removed from the live site.

This would explain why he could reproduce it and no one else could. It would also explain why it persisted after Tidio was uninstalled—cached resources don’t care what’s currently on the server.

But I couldn’t verify this theory. The friend’s browser was now compromised, any cache had been polluted by the malware he’d accidentally downloaded, and there was no way to examine what he’d originally been served.


Escalating to the Platforms

I escalated to both Tidio and Shopify support, looking for logs that might reveal what I couldn’t see.

To Tidio, I requested backend login history, configuration change logs, session records, and API access logs. The ticket was escalated to their Legal team with a 24-hour SLA.

To Shopify, I requested Script Tags history (apps can inject scripts via API without modifying theme files), app install/uninstall logs, and theme modification records.

Shopify’s response was illuminating. They confirmed Tidio was installed December 30th at 17:26 UTC and removed January 3rd at 22:44 UTC. More importantly: no Script Tags had been registered by Tidio or any other app since Klaviyo back in August. No theme modifications by apps during the incident window.

If Tidio had injected malicious code through Shopify’s official Script Tags API, it would have shown up here. It didn’t.


What Was Left

With Shopify’s Script Tags ruled out and Tidio’s JavaScript confirmed clean, I was left with hypotheses I couldn’t directly verify:

Tidio conditional serving: It’s possible Tidio’s CDN briefly served different code to certain user profiles while showing clean code to everyone else, including my analysis. This is how sophisticated Magecart-style attacks work. The clean code I analyzed may never have been the problem because I was never the target audience.

Tidio account compromise: The Upwork developer had been given Tidio credentials directly. If those credentials were compromised—whether through the developer’s own system being infected or through credential reuse—an attacker could have configured malicious code that was later removed.

Client-side compromise: The friend’s browser may have had a malicious extension before he ever visited the site. Shopping and coupon extensions are common vectors—they have broad permissions to inject JavaScript into e-commerce pages. Some target specific platforms or even specific stores. The Tidio installation timing could have been coincidental, or the extension could have activated specifically on sites with chat widgets.

Browser cache serving stale malicious content: If the friend’s browser cached a page version that included malicious code, he might have continued seeing redirects after the live site was clean.

Without Tidio’s server-side logs, without access to the friend’s browser before it was compromised, and without a reproducible test case, none of these could be confirmed or ruled out.


The Reality of Inconclusive Investigations

In security work, there’s often pressure to deliver a definitive answer. But the reality is that many investigations end without one.

According to the Identity Theft Resource Center, 69% of data breach notices in the first half of 2025 didn’t include root cause information. A Foundry Security Priorities study found 57% of security leaders struggled to find root cause of incidents in the past year. This isn’t failure—it’s the nature of investigating sophisticated attacks where adversaries actively cover their tracks.

Whoever was behind this campaign knew what they were doing. They registered a disposable domain weeks before the attack, appeared to configure sophisticated fingerprinting to evade analysis environments, and either injected briefly enough to avoid capture or leveraged client-side compromise that leaves no server-side evidence.

Evidence preservation matters as much as remediation. When the client removed Tidio before calling me, he eliminated the primary forensic opportunity. When his friend interacted with the scareware page, he destroyed the evidence on his end. These were understandable decisions made in the moment, but they closed doors that can’t be reopened.


What I Delivered

Despite the inconclusive root cause, the engagement delivered concrete value:

Site verification: Comprehensive analysis confirmed no active threats in theme files, installed apps, customer pixels, checkout scripts, or live page source. The store was clean.

Platform education: The client now understands how Shopify’s app ecosystem creates attack surface, how Script Tags API works, and why evidence preservation matters.

Hardening recommendations: I provided practical steps including 2FA enforcement across all accounts, staff and collaborator access review, app vetting protocols, theme update procedures, and monitoring approaches appropriate for standard Shopify (not requiring the $2,500/month Plus tier).

Incident response framework: Documentation of what to do if this happens again—critically, what evidence to preserve before taking remediation steps.

Cleanup items: Identified orphaned scripts from a previously uninstalled subscription app and a dead polyfill.io reference (from the 2024 supply chain attack, now non-functional but worth removing as technical debt).


Lessons for Other Business Owners

Don’t share credentials with contractors. Use platform-native collaborator access wherever possible. When you share a password, you lose visibility into what happens with it.

Preserve evidence before remediation. If something suspicious happens, document everything before making changes. Screenshot the app list, export the theme, capture the page source, note the timeline. Call in help before removing the suspected cause.

The person who can reproduce the issue is valuable. Get them on a call, capture their network traffic, understand their setup—before they interact further with anything malicious.

Not every investigation ends with certainty. And that’s okay. The site was secured. The threat was mitigated. The client is better prepared for next time. That’s what matters.


Stonegate Web Security provides incident response and security consulting for small businesses. If your website has been compromised, reach out—ideally before you remove anything.

Related Reading