Your Shopify Theme Can Be Clean While Your Checkout Is Being Hijacked

Your Shopify Theme Can Be Clean While Your Checkout Is Being Hijacked

Two technical reports describe Shopify checkout phishing redirects delivered through app integrations. Here is what they reveal about remote configuration, third-party scripts, and storefront supply-chain security, and what merchants and app founders should do now.

By Yuvraj Kewate ยท 2026-10-15

Two technical reports describe phishing redirects involving different Shopify app integrations. The deeper concern is what they reveal about remote configuration, third-party scripts, and the security of the storefront supply chain.

A shopper adds a product to their cart and clicks Checkout. The store looks normal. The cart is correct. The products, quantities, and total are exactly what the customer expects.

Then they land on a page that looks like Shopify checkout but isn't.

They begin entering their payment details. In one reported case, the fake form allegedly forwarded the shopper to the legitimate Shopify checkout afterward, allowing the order to complete normally. The merchant could see a sale. The customer could still have been phished.

That is what makes this class of attack particularly dangerous: a fraudulent checkout can be inserted into an otherwise ordinary shopping journey without necessarily breaking the store's visible functionality.

Two public technical accounts describe suspicious checkout redirects involving different Shopify app integrations. Developer Roman Zipp documented a case involving Product Options by HulkApps. Dan Sutherland, Delivery Director at Shopify Plus agency Underwaterpistol, described another involving Swym Wishlist Plus.

The reports describe different mechanisms for delivering the suspicious code. Subsequent merchant reports also raised concerns about similar phishing domains appearing on stores that reportedly had neither app installed.

The evidence available in these accounts does not establish who was responsible, how the payloads were introduced, or whether every reported incident shared the same operator. But the similarities warrant attention, and the differences matter.

We have reached out to both Swym and HulkApps for comment on the reported incidents and the questions they raise about storefront security. We are awaiting their responses and will update this article if they provide further information.

This is not simply a story about whether one app is safe or unsafe. It is a story about a broader security problem: the code running on a Shopify storefront can change after installation, without the merchant changing a single line of their theme.

Two incidents, two reported paths to a fake checkout

The first account came from Roman Zipp, who published a technical investigation after encountering a suspicious checkout while shopping on mechanicalkeyboards.com on October 10.

The second came from Dan Sutherland, who described his team's investigation of checkout redirection on a client storefront using Swym Wishlist Plus.

The two accounts point to different app integrations and different ways in which suspicious code reportedly reached the browser. Both describe a customer being diverted from a legitimate shopping journey to an external checkout imitation.

ReportApp or storefront contextReported delivery mechanism
Roman Zipp, October 10Product Options by HulkAppsA custom_js value returned through the app's API
Dan Sutherland, UnderwaterpistolSwym Wishlist PlusA long HTML string returned in place of a wishlist button label
Subsequent merchant reportsStores reportedly without either app installedDelivery mechanism not established in the accounts available

The domains and behavior described in these reports appear similar enough to justify investigating a possible connection. But that is not proof of a single campaign, a shared attacker, or a common initial compromise.

The distinction is important. Security reporting should explain what investigators observed, what those observations suggest, and what remains unknown.

Incident one: the custom JavaScript field

In his October 10 write-up, Zipp described shopping on mechanicalkeyboards.com when clicking Checkout took him to a page hosted on biliing[.]top, a domain resembling a checkout-related address.

The page looked suspicious enough that he investigated further. One clue came from his password manager: it offered to fill his credit card name into a first-name field on the unfamiliar page.

Zipp examined the checkout interaction in Chrome DevTools. The checkout button itself did not have the suspicious listener he expected to find, so he used event-listener breakpoints to follow the execution path through the page.

That led him to a function named hijack, which, according to his write-up, had been injected at runtime rather than appearing as a conventional source file in the theme.

Tracing the call stack led to hulkcode.js, a script served through Shopify's CDN as part of the Product Options by HulkApps theme app extension.

The script made a request to HulkApps' API. The response included a field called advanced_users.custom_js, containing approximately 22.7 KB of JavaScript. Zipp identified that field as the source of the reported hijack script.

The important distinction is that the theme extension's script was not necessarily the complete payload. It fetched additional content from a remote service after the storefront loaded.

That architecture can be entirely legitimate. Apps frequently retrieve configuration and other data from their own services. But when remotely returned content can execute as JavaScript, the security of the storefront depends on more than the code initially delivered with the app.

Zipp also documented behavior that could make the incident difficult to reproduce. The script reportedly ran once per browser session and set a flag in sessionStorage, preventing the same shopper from being redirected repeatedly during that session.

In his test, submitting information to the fake form allegedly sent the data to the phishing domain before redirecting the shopper to the real Shopify checkout.

That final detail matters. A completed order would not, by itself, prove that the customer had followed a legitimate checkout path from beginning to end.

What the investigation established, and what it did not

Zipp identified several possible explanations for how the malicious code reached the configuration field. These included a compromised merchant account, a compromised employee account, a compromise of the app provider's systems, or another app modifying the configuration.

He did not establish which explanation was correct.

According to his account, Shopify escalated the report internally, and the visible hijack on mechanicalkeyboards.com disappeared within approximately 16 minutes. The store also confirmed that it had removed the app.

The account did not establish how many other stores might have been affected or identify the initial point of compromise.

That uncertainty should remain explicit. Finding malicious code in a configuration field is not the same as proving how it got there, who placed it there, or which other installations were exposed.

Incident two: when a wishlist button label allegedly carried executable code

The second account describes a different route to similar visible behavior.

Dan Sutherland of Underwaterpistol said his team investigated checkout redirection on a client store using Swym Wishlist Plus. The team initially removed another recently installed app that had been suggested as the cause, but the behavior continued.

That is a useful investigative lesson in itself: the first suspicious component is a lead, not necessarily the source.

According to Sutherland, further tracing pointed to Swym's configuration endpoint:

swymrelay.com/api/v3/provider/checkAndGet

The response allegedly contained a string thousands of characters long where the interface expected the English label for an "Add to Wishlist" button.

Inside that string, Sutherland reported finding a hidden broken image with an onerror handler.

The reported mechanism depended on how the app handled the response. Swym's storefront script wrote the returned label into a wishlist button. When the embedded image failed to load, its error handler allegedly executed.

In other words, the value presented as a button label was reportedly interpreted as HTML containing executable behavior.

Sutherland said his team observed a script that intercepted multiple customer interactions, including checkout-button activity, cart form submissions, pointerdown, and mouseover events. The script allegedly redirected shoppers to external pages, including account-confirm[.]top and billing-confirm[.]top.

His account also described the fake checkout reproducing the customer's basket, including products, variants, quantities, totals, and currency. The script reportedly polled Shopify's /cart.js endpoint every 20 seconds to keep the copied cart data current.

Another detail concerned browser-side caching. Sutherland said the configuration was stored in localStorage under the key swym-rconfig_cache. In his team's testing, disabling the app did not immediately eliminate the behavior: the cached handler remained, and a subsequent request reportedly returned the suspicious content again.

Sutherland also reported seeing the same handler load on another store using the app. In that case, custom wishlist buttons appeared to prevent the same visible checkout hijack.

If accurate, that observation illustrates a significant distinction: suspicious code may be present without producing identical visible behavior on every storefront. The result can depend on the page markup, the app's execution path, and the customer's interactions.

These details are Sutherland's reported findings. They should not be treated as independently verified conclusions about the origin of the payload, the full number of affected stores, or the current status of the endpoint.

The common thread: remote configuration can become a code-execution path

The HulkApps and Swym reports describe different mechanisms, but they raise a shared architectural concern.

In the first account, the app fetched a field explicitly intended to contain custom JavaScript. In the second, a value expected to be a text label allegedly contained HTML with an executable event handler.

The distinction is important. A custom JavaScript field is designed to carry code, even though it creates an obvious security risk if an unauthorized party can modify it. A button label should be plain text. If a label can become executable HTML, the implementation has allowed data to cross into a code-execution context.

The broader pattern can be summarized like this:

Security questionWhy it matters
What code runs initially?The installed extension or script may be reviewed, versioned, and delivered through a trusted distribution path.
What does it fetch afterward?Remote services can change the content a storefront receives after installation.
How is that content handled?Unsafe DOM insertion can turn a data field into an execution path.
Who can modify the remote configuration?Compromised accounts or inadequate access controls may expose every store that consumes the configuration.
Can the behavior persist in a browser?Cached payloads can complicate containment and verification.

This is the core lesson for app developers: the security of a storefront integration depends not only on the script delivered at installation, but also on the data and code it consumes later.

A clean theme extension does not guarantee that every future response from the app's servers will be safe.

Likewise, the presence of suspicious content in a remote response does not, by itself, establish how that content was introduced. The relevant account, dashboard, server, or dependency still needs to be investigated.

Are these incidents part of one campaign?

The reported phishing domains and checkout behavior raise the possibility that the incidents are connected. Subsequent merchant reports described similar domains appearing on stores that reportedly did not have either of the two apps installed.

That is a significant lead, but not a complete explanation.

There are several possibilities: the reports could involve a shared attacker exploiting different weaknesses, separate incidents using similar phishing infrastructure, or another common factor that has not yet been identified.

The available accounts do not establish which explanation is correct. Nor do they establish that the reported stores without either app were compromised through the same delivery mechanism.

The distinction matters because it changes the investigation.

If the issue is confined to a particular app's configuration service, remediation may focus on that provider's systems and the stores consuming its responses. If the same phishing infrastructure is being introduced through multiple unrelated routes, removing one app will not necessarily address the wider threat.

Merchants should therefore avoid assuming that a store is safe solely because it does not use either app named in the reports. Equally, they should not assume that every store using either app has been compromised.

The right response is to investigate observable behavior: unexpected checkout redirects, unfamiliar domains, suspicious scripts, and unusual network responses.

Why this matters for Shopify's security model

Shopify's app ecosystem gives merchants a powerful way to extend their stores without building every feature from scratch. Wishlist tools, product options, reviews, loyalty programs, subscriptions, analytics, and personalization can all become part of a merchant's technology stack.

That convenience depends on trust.

An app may introduce a storefront script, use a theme app extension, retrieve configuration from its own infrastructure, and rely on additional third-party services. The merchant may have control over the theme while having limited visibility into the behavior of every remote dependency.

The practical security boundary is therefore larger than the theme editor.

It includes installed apps, embedded scripts, external endpoints, remote configuration, browser-side storage, and the accounts authorized to change those systems. We explored this shift in depth in our piece on why Shopify apps are the new security perimeter.

A review at installation time cannot guarantee that the app's runtime behavior will remain unchanged. Remote configuration is useful precisely because it can change without a full redeployment. The same flexibility means that the consequences of a compromised configuration system can extend to every storefront that consumes its output.

This is a software supply-chain problem: the merchant relies on code and services they do not operate directly, and a change somewhere in that chain can affect the storefront.

The lesson is not that Shopify apps are inherently unsafe. It is that trust in a third-party integration needs to be maintained throughout its lifecycle, rather than treated as a one-time decision.

What Shopify app founders should change

For developers building Shopify apps, the most useful response is to examine the paths through which remote data reaches the storefront and the authority those paths provide.

1. Treat remote values as data, not executable markup

If a field is supposed to contain a button label, render it as text. Use safe DOM APIs such as textContent instead of inserting untrusted values through innerHTML.

Validate values on the server, enforce reasonable length and format constraints, and reject unexpected content.

A wishlist label should not need to contain thousands of characters of HTML. A validation rule would not solve every security problem, but it could help detect an anomalous response before it reaches the browser.

2. Treat custom JavaScript as a high-risk capability

If an app supports custom JavaScript or HTML, assume that unauthorized modification could affect every storefront consuming that configuration.

Ask whether the feature is essential. Where it remains necessary, restrict who can edit it, require strong authentication, record every change, notify the relevant account owner, and provide version history and rollback.

Custom code is not merely another settings field. It can change what executes in the customer's browser.

3. Secure the dashboard and configuration pipeline

Review every account that can modify merchant settings, remote configuration, or custom code. Enforce multifactor authentication, remove unnecessary privileges, and audit access by employees, contractors, and support personnel.

Where appropriate, use Shopify's supported authentication and authorization mechanisms rather than maintaining unnecessary parallel credential systems.

Log changes to sensitive configuration and make those logs available during an incident. If a suspicious payload appears, investigators need to establish who changed the relevant value, when it changed, and which stores received it.

4. Monitor configuration for anomalies

Remote configuration should have expected formats and reasonable size limits.

A field that normally contains a short text label should trigger an alert if it suddenly contains thousands of characters, script tags, event handlers, unfamiliar domains, or code-like content.

For fields intended to contain code, the controls need to be stricter still. Monitor unexpected changes, restrict modification rights, and maintain a reliable audit trail.

The goal is not to block every unusual string through simplistic keyword matching. It is to make unexpected changes visible and ensure that configuration values cannot silently acquire more authority than intended.

5. Keep each feature within its intended scope

A wishlist feature should not need to monitor every checkout interaction. A product-options widget should not require unrestricted control over unrelated customer journeys.

Scope event listeners to the elements and interactions the feature actually needs. Avoid global handlers that can intercept unrelated actions unless there is a clear, justified requirement.

The less authority a component has, the less damage it can cause if that component is compromised.

6. Design caches for invalidation

If an app stores configuration in localStorage or another client-side cache, give that data an explicit version and expiration policy.

Plan for emergency invalidation. When a malicious or malformed configuration is discovered, developers need a way to prevent affected clients from continuing to use it and to verify that the remote source no longer serves it.

Clearing browser storage may help during investigation, but it is not a substitute for fixing the source. A payload that is fetched again after storage is cleared remains a live problem.

7. Build a kill switch into the operating model

App developers should be able to disable a compromised configuration or feature quickly across affected stores. That requires more than a support email address: it requires operational controls, monitoring, an incident owner, and a tested response process.

Security contacts should be easy to find. Reports should be acknowledged quickly, and the team should be able to notify merchants with clear instructions when a genuine risk is identified.

A well-designed kill switch can reduce the time between discovery and containment. In a checkout phishing incident, that time matters.

What merchants and agencies should do now

Merchants do not need to reverse-engineer every app to take sensible precautions. They do need a plan for investigating unusual checkout behavior and a way to act quickly when credible evidence points to a live risk.

Test the complete checkout journey

Open a fresh private browsing session, add a product to the cart, and follow the expected path to checkout. Verify the destination URL.

Repeat the test using the cart page, cart drawer, relevant checkout buttons, and other purchase paths used by the theme. If the behavior appears intermittent, test across fresh sessions rather than relying on a single successful attempt.

An unexpected redirect to an unfamiliar domain should be treated as a serious warning sign.

Contain first when there is credible evidence of an active hijack

If customers are being redirected to a suspected fraudulent checkout, disable the affected app or its relevant embed while investigating. If the source cannot be isolated promptly and customers remain exposed, temporarily taking the storefront offline may be safer than allowing the behavior to continue.

Do not leave an active risk in place simply because the cause has not yet been conclusively identified.

Preserve evidence

Record the destination URL, timestamps, screenshots, browser behavior, relevant network requests, and any suspicious configuration responses. Preserve enough information for the app developer and Shopify Support to reproduce and investigate the problem.

Avoid making unsupported public accusations while the cause is still being established. A precise technical report is more useful than speculation.

Check the entire app stack

Removing one suspicious app does not establish that the storefront is clean. Review other apps that inject scripts or theme embeds, inspect unexpected external requests, and test whether the behavior returns in a clean browser session.

If browser storage may be involved, clear it as part of a controlled retest. But do not treat a clean session as proof that the remote source has been fixed.

Review account access

Change credentials if compromise is suspected, enable multifactor authentication, and remove unfamiliar staff or collaborator accounts. Pay particular attention to app dashboards that allow users to edit custom code or storefront configuration.

Assess customer impact

A successful order does not necessarily mean that the entire journey was legitimate. If a customer may have entered payment information on a fraudulent page, involve the appropriate security, payments, and legal teams to determine the extent of exposure and whether customers need to be notified.

Do not assume that every reported redirect resulted in payment-data exposure. Equally, do not use a completed order as proof that no information was compromised.

Agencies: maintain an app inventory

Agencies managing multiple stores have an additional responsibility. Maintain a current inventory of which apps are installed on which client stores, which ones inject storefront scripts, and who is responsible for investigating security alerts.

When an app is implicated in a credible report, that inventory makes it possible to assess exposure across the client portfolio quickly instead of discovering the affected installations one by one.

The question app founders should be asking

The Shopify ecosystem works because merchants can combine specialized tools into a sophisticated commerce operation. That flexibility is one of its strengths, and it should not be undermined by treating every app as an inherent threat.

But app developers need to think beyond whether their initial code is safe.

They need to ask what happens if a dashboard account is compromised, a configuration value is modified, a third-party service returns unexpected content, or a cached payload needs to be revoked immediately.

They also need to ask whether a feature has more access to the storefront than it actually needs.

These are not abstract questions. They determine whether a compromised setting can affect one merchant or thousands, whether an anomaly is caught before customers encounter it, and whether an incident can be contained in minutes rather than days.

The reports involving HulkApps and Swym raise these questions through two different technical paths. The reported cases do not, by themselves, establish the full cause or scope of the incidents. That requires further evidence and clear responses from the relevant parties.

But the engineering principle stands regardless: a storefront integration is not just the code delivered when the merchant installs it. It is the entire system of scripts, configuration, accounts, services, and cached data that continues to influence the customer experience afterward.

A clean theme is not a clean storefront.

And a trusted app is not a permanently trusted dependency. Its security must be maintained for as long as it runs on a merchant's store.


Reporting note: This article draws on the technical account published by Roman Zipp, the incident description shared by Dan Sutherland of Underwaterpistol, and merchant reports on the Shopify Community forums. We have reached out to Swym and HulkApps for comment and are awaiting their responses. The technical behavior and attribution described in the reports should be treated as reported findings unless independently confirmed. A connection between the incidents remains a hypothesis, not an established conclusion. We will update this article if the companies provide substantive responses or new evidence emerges.

Your Shopify Theme Can Be Clean While Your Checkout Is Being Hijacked