WordPress Funnel Builder Compromise: What Every SMB With a Website Should Check

The morning of May 18 brought another one. Active exploitation, in the wild, against a popular WooCommerce funnel-and-upsell plugin called Funnel Builder by FunnelKit, with attackers injecting card-skimming JavaScript into the checkout pages of every store running an unpatched copy. The plugin is on the order of 40,000 active installs. The skimmer is well built and quiet. Most affected merchants will not notice on their own.

I want to walk through what happened, exactly what an SMB site owner should check today, what to do in the first hour if you find indicators of compromise, and what the durable defensive baseline looks like for any small business with a WordPress store. The post is intentionally operational. If you own a Central Coast e-commerce site and the next 30 minutes is the time you have, this is what I would do with it.

What happened

Funnel Builder by FunnelKit is a WordPress plugin that adds sales funnel, upsell, and checkout-optimization features on top of WooCommerce. It is one of the better-regarded plugins in the WooCommerce ecosystem, used heavily by SMBs that sell info-products, digital downloads, and direct-to-consumer goods. The vulnerability is in how the plugin handles its "External Scripts" setting, which is meant to let store owners drop in legitimate third-party tags (Google Tag Manager, Meta Pixel, analytics, etc.) that should fire on the checkout flow.

The bug, fixed in version 3.15.0.3, allowed unauthenticated attackers to write arbitrary content into that External Scripts field. Once a script lands there, it executes in every visitor's browser on every checkout page. There is no authentication step. There is no admin involvement. The attacker writes, the customer's browser runs it.

The class of bug here is a classic "stored cross-site scripting via a sensitive configuration sink." It is the same shape we have seen many times in the WordPress plugin ecosystem over the years: a configuration write endpoint that the plugin author assumed only admins could reach, but which a missing capability check or a broken nonce allows anyone on the internet to call. The class is unglamorous and well understood; the consequences when a plugin sits on checkout pages are not.

What the payload does

The observed payloads in this campaign are well-engineered. They masquerade as a Google Tag Manager loader so that a casual look at the page source sees what appears to be a normal GTM include and moves on. The injected loader actually establishes a WebSocket connection to an attacker-controlled command-and-control endpoint (one publicly reported address: wss://protect-wss[.]com/ws) and pulls down a second-stage skimmer tailored to the specific theme and checkout layout of the victim store.

The skimmer hooks the checkout form. When the customer types their card number, expiration date, CVV, name, and billing address, the skimmer reads those values out of the DOM, packages them, and ships them back out over the same WebSocket. The customer's order then completes normally through Stripe, Square, Authorize.Net, or whatever processor the store actually uses. From the customer's perspective, nothing went wrong. From the store owner's perspective, orders shipped and revenue came in. The card data, meanwhile, is in an attacker's hands within seconds of being typed.

Why this category of attack is everywhere

E-skimmers (sometimes called Magecart-style attacks after the loose collective that pioneered them on Magento) are the dominant card-fraud monetization path for compromised e-commerce sites in 2026. The economics are good: a successful injection runs invisibly for weeks, captures every card that flows through the checkout, and feeds card-shop marketplaces where the data is sold in batches. The infrastructure cost to the attacker is low. The detection rate on the merchant side is low. The criminal returns are high.

Plugin-based injection vectors like this one are particularly attractive because the attacker does not need to compromise the host, the database, or the WordPress core. A single HTTP request to a vulnerable plugin endpoint writes the skimmer, and the plugin happily serves it back to every visitor. From an attacker's point of view, that is a phenomenal return on investment.

How to tell if your site is affected

Six concrete checks, in order. None of them require a developer. All of them take longer to explain than to actually do.

1. Confirm whether Funnel Builder is even installed

Log into /wp-admin, click Plugins in the left sidebar, and look for an entry titled Funnel Builder by FunnelKit (the related plugins FunnelKit Automations and FunnelKit Stripe Gateway are separate products from the same vendor and are not the vulnerable component in this campaign). If Funnel Builder is not in the list, this specific bug is not your problem. Move on to the broader checks below.

2. Check the plugin's installed version

If Funnel Builder is installed, look at the version number listed under the plugin name. If it is 3.15.0.3 or later, the bug is patched on your site. If it is anything earlier, you are running a vulnerable version. Click Update Now. If for any reason you cannot update immediately (custom modifications, staging concerns, a hosting plan that has plugin updates locked down), deactivate the plugin until you can update. A deactivated plugin's code does not execute and is not exploitable.

3. View source on your checkout page

Open an incognito browser window, go to your live checkout URL (typically /checkout), and view the page source (Ctrl+U or right-click and choose "View page source"). Use the browser's find function to search for <script. Walk down the list of script tags and ask, for each one whose src points to an external domain, whether you recognize the domain. Domains you should expect to see include your own, your CDN (Cloudflare, Fastly), Google (gtm.js, analytics.js, gstatic), Meta (connect.facebook.net), Stripe (js.stripe.com), and any analytics or chat tool you have installed deliberately.

Domains you should not see and should treat as indicators of compromise: anything that vaguely resembles a legitimate service but is not (googl-tagmanager instead of googletagmanager, stripe-js instead of js.stripe.com, random hyphenated lookalikes), and anything pointing to a domain you cannot identify with one quick search. The specific C2 reported in this campaign was protect-wss[.]com, but attackers rotate infrastructure constantly. Treat any unfamiliar external script on your checkout page as guilty until proven innocent.

4. Audit Funnel Builder's External Scripts setting directly

In wp-admin, navigate to FunnelKit → Settings → Checkout (the exact menu path varies slightly by version) and find the External Scripts configuration. Read every line. If you see code you do not remember adding and that does not match a tag your marketing team or developer would have placed there, copy it somewhere safe for evidence and then delete it. The injection sink in this attack is exactly this field.

5. Pull 30 days of processor logs

Log into your payment processor's dashboard (Stripe, Square, Authorize.Net, PayPal, whatever) and review the last 30 days of transactions for unusual patterns: small test charges from unfamiliar countries, repeat declines on cards that subsequently succeed elsewhere, refunds you did not issue. Skimmer operators often test stolen cards through legitimate-looking merchants to validate them before listing them for sale. If a meaningful number of your recent transactions match that pattern, your site was likely compromised some time ago.

6. Audit WordPress users

In wp-admin, click Users and look at the full user list. Sort by role and confirm that every account with Administrator, Editor, or Shop Manager privileges belongs to a person you know. Attackers who get a foothold through one vulnerability often create a persistence account so they retain access even after the original bug is patched. Any admin user you do not recognize gets deleted, and the password on every legitimate admin gets reset.

What to do right now (if you found anything)

If any of the checks above turned up an indicator of compromise, here is the emergency-response order I would run. The goal of these steps, in priority order, is: stop the bleeding, evict the attacker, preserve evidence, and notify the parties who legally need to know.

  1. Update or deactivate Funnel Builder. Get to 3.15.0.3 or later, or turn the plugin off entirely. This closes the original injection sink so the attacker cannot simply re-inject after you clean up.
  2. Remove the injected scripts from Settings → Checkout → External Scripts. Save your changes. View the checkout page source again in an incognito window and confirm the unfamiliar scripts are no longer being served.
  3. Force-reset every admin and shop-manager password. In Users, edit each privileged account and either send a password reset email or set a new password directly. Do not let the prior credentials remain valid.
  4. Force-reset customer passwords if customer accounts also touch sensitive data on your site. WooCommerce supports a bulk-reset workflow; use it.
  5. Rotate WordPress salts by generating a new set at the WordPress.org secret-key URL and pasting them into wp-config.php, replacing the existing AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, AUTH_SALT, SECURE_AUTH_SALT, LOGGED_IN_SALT, and NONCE_SALT lines. Save the file. This invalidates every existing session cookie on the site, including any the attacker may still be holding.
  6. Run a full security scan with Wordfence (free version is fine for this) or Sucuri SiteCheck. The scan looks for known web shells, backdoors, modified core files, and additional injected scripts elsewhere in the site. Investigate every finding.
  7. Review .htaccess at the WordPress root and in /wp-admin/ for injected redirect rules. Attackers sometimes plant entries that quietly send certain visitors (search-engine crawlers, mobile users) to malicious destinations.
  8. Audit wp-content/plugins/ and wp-content/themes/ via your hosting file manager or SFTP for unfamiliar files, especially in obscure subdirectories. Common attacker plant locations include theme function files, plugin uploads directories, and randomly-named PHP files in wp-content/uploads/.
  9. If you are PCI in scope (storing, processing, or transmitting cardholder data, including via redirect or iframe checkouts under PCI DSS v4), notify your acquiring bank and payment processor in writing. Do this before they reach out to you. The penalty structure for self-reporting is materially better than for being caught hiding it. Expect a PCI Forensic Investigator engagement.
  10. Preserve evidence before you wipe anything. Take a full backup (files plus database) of the compromised state and store it offline. If there is later litigation, an insurance claim, or a forensic process, that evidence matters.

If you are not confident running any of these steps, this is the moment to bring in a professional. Our website development team handles WordPress incident response for Central Coast SMBs, and our cybersecurity practice handles the broader environment hardening. The cost of an hour or two of help here is dramatically lower than the cost of a continued skimmer run.

The defensive baseline for any SMB WordPress site

Whether or not this particular bug affected you, the cluster of controls that meaningfully reduces the probability of the next WordPress compromise is short and well understood. Run all of them. They are not exotic.

A web application firewall in front of the site

Cloudflare Pro (around $25 per month per zone) or Wordfence Premium (around $150 per site per year) sits between the internet and your WordPress origin and blocks the bulk of automated exploit attempts before they reach the plugin. WAFs do not catch everything, but they catch the noisy mass-scan traffic that is responsible for the majority of opportunistic compromises. For an SMB, this is one of the highest-leverage $25-per-month decisions available.

MFA on wp-admin

Wordfence and the standalone Two Factor Authentication plugin both add proper MFA to WordPress admin login. Require it on every administrator and editor account. Username and password are not adequate for any account that can modify code or content in 2026, including on WordPress.

Least-privilege admin accounts

Most WordPress sites I audit have three to five users with full Administrator privileges where they only needed Editor or Shop Manager. Demote them. The blast radius of any one account being phished or breached is bounded by what that account can do.

Plugin minimization

The average SMB WordPress site I see has thirty-plus plugins installed. Half are unused. Quarter have not been updated by their author in years. Plugin sprawl is the largest single factor in WordPress attack surface. Every quarter, walk the plugin list and ask "do we actively use this, and is it being maintained." Remove anything that fails either test. Prefer plugins from reputable authors (Automattic, Yoast, WP Rocket, FunnelKit, WP Engine, etc.) over unmaintained one-developer projects.

Automated daily off-site backups

UpdraftPlus pointed at an S3 bucket or a Backblaze B2 bucket, running daily, with a 30-day retention. Off-site means not on the same server as the site. Daily means you have a recovery point within 24 hours of any compromise. The combination is what lets you confidently roll back a compromised site instead of trying to clean it in place. Tied directly to our backup and disaster recovery practice for the same reason.

File integrity monitoring

Wordfence does this for free at a basic level. The premise is simple: WordPress core, plugin, and theme files should not change between releases. When they do, something is wrong. A file-change alert is often the earliest detection signal for a backdoor or web shell.

Kept-current PHP and WordPress core

Confirm your hosting environment is on a supported PHP major version (PHP 8.2 or later as of mid-2026) and that WordPress core is on the current major. Out-of-support PHP gets no security patches, and out-of-support WordPress versions accumulate known issues that the bulk-scanner ecosystem actively exploits.

Hosting that supports the rest of the program

Cheap shared hosting where dozens of sites share a single uid does not let you isolate a compromise. Managed WordPress hosting (Kinsta, WP Engine, Pressable, Rocket.net) gives you account isolation, automated daily backups at the platform level, staging environments, and a meaningful response if the host detects malware. The cost difference is usually $20-50 per month and is worth it for any site that takes payments. We cover hosting selection in our cloud services practice.

Why this keeps happening to WordPress

An honest take, because most of the WordPress security commentary online is either marketing or doom-mongering.

WordPress runs roughly 40 percent of the public web. That alone makes it a target of disproportionate attention. The platform itself, meaning core WordPress, is reasonably well-maintained and has a credible security team. The vast majority of WordPress compromises do not exploit core; they exploit the plugin ecosystem layered on top.

The plugin ecosystem has structural problems that the WordPress.org plugin directory does not solve:

  • No consistent security review. Plugins submitted to the directory get a sanity-check review on initial submission. Subsequent updates do not. A plugin can ship a perfectly clean version 1.0 and a deeply vulnerable version 1.4 without any review gate in between.
  • Plugin sprawl. The average site has dozens of plugins. The probability that at least one of them has a critical issue in any given year approaches certainty by the math.
  • Abandoned plugins. A non-trivial fraction of installed plugins are no longer maintained. The original author moved on, the company that bought it deprioritized it, or it was never going to be a real product. Vulnerable code sits in production until someone notices.
  • Weak shared hosting. A lot of WordPress lives on shared hosting where one compromised site on the same server can sometimes touch others. SMBs gravitate to this hosting tier because it is cheap.
  • Supply-chain risk. A reputable plugin gets sold to a different company, and the new owner injects monetization (or, in the worst cases, malware) in a future update. Site owners auto-update and trust the name on the plugin, not realizing the maintainer changed.

None of this is a reason to abandon WordPress. For most SMB use cases, the alternative is more expensive and less flexible. It is, however, a reason to operate WordPress with the discipline you would apply to any production system: short plugin lists, current versions, MFA on admin, a WAF in front, and backups you have actually tested. The discipline is not glamorous. It is what works.

Where this fits with the rest of the week

This post lands in the middle of a cluster of related pieces in the cybersecurity and website-development sections of the blog:

If you take one thing from this article, take this: a WordPress site that processes payments is a production system. Treat it like one. The plugin you installed three years ago and forgot about is still running on every visitor's checkout page, and someone is paid to find the next bug in it.

FAQs about the Funnel Builder compromise

Is my site affected if I do not use Funnel Builder?

Not by this specific bug. The vulnerability is in the Funnel Builder by FunnelKit plugin and is exploitable only on sites where that plugin is installed and active. If you log into wp-admin, go to Plugins, and Funnel Builder does not appear in the list, this incident is not your immediate problem. That said, the same class of attack (an unauthenticated injection point in a third-party plugin that ends up writing attacker-controlled JavaScript into your checkout page) is one of the most common compromise paths for WooCommerce sites in 2026. Treat this as the prompt to do the broader checks below: scan with Wordfence or Sucuri, audit your installed plugins, and confirm you are on current versions.

Should I just turn off all plugins?

No. Disabling every plugin on a live store will break the site, often including the checkout itself. The right move is targeted: confirm whether Funnel Builder specifically is installed, and if so, update it to 3.15.0.3 or later, or deactivate that one plugin until you can update. After the immediate exposure is closed, do a broader plugin audit: remove plugins you do not actively use, replace anything that has not been updated by its author in the last 12 months, and consolidate redundant plugins. Plugin minimization is one of the highest-leverage things an SMB can do to reduce WordPress attack surface, but it is a planned activity, not an emergency one.

We use Shopify, Squarespace, or a non-WordPress platform. Are we affected?

Not by this specific vulnerability. Funnel Builder by FunnelKit is a WordPress plugin and only runs on WordPress sites with WooCommerce. Shopify, Squarespace, Wix, BigCommerce, and other hosted SaaS storefronts use entirely different codebases and are not exposed to this bug. That said, e-skimmer attacks against hosted platforms exist too. They typically come in through a compromised marketing tag, a malicious third-party script (a chat widget, an analytics plugin, a review widget), or a stolen admin credential. The same defensive baseline applies: MFA on admin accounts, minimize installed apps and tags, review what scripts run on your checkout.

How quickly do these card-skimming attacks get noticed?

Honestly, slowly. In the small-business breaches I have walked into, e-skimmer injections often run for weeks or months before anyone notices. The site loads normally. Checkout completes normally. Real orders go through and ship. The skimmer simply copies the card details on their way to the legitimate payment processor and sends them to an attacker-controlled domain. Detection usually comes from one of three places: the card brands flag the merchant as a common point of purchase for fraudulent cards, a customer complains about fraud after shopping with you, or a security scanner (Sucuri, Wordfence, PCI ASV) spots the unfamiliar script. By the time the merchant gets the call from their processor, the damage is several thousand customers deep.

What does rotating WordPress salts actually do?

WordPress uses a set of secret keys (called salts) stored in wp-config.php to sign authentication cookies. If an attacker stole a session cookie or a copy of your database while they had access, rotating the salts invalidates every existing logged-in session on the site. Every user, including the attacker if they still have a foothold, is forced to re-authenticate. You generate new salts at the WordPress.org secret-key service URL, paste them into wp-config.php replacing the eight AUTH_KEY / SECURE_AUTH_KEY / etc. lines, save, and confirm the site still loads. It is a cheap, fast, high-value step after any suspected WordPress compromise.

We are PCI in scope. What changes for us?

Several things. First, if you store, process, or transmit cardholder data on your WordPress site (including iframe-redirect setups that PCI DSS v4 now treats as in scope), a confirmed e-skimmer injection is a reportable incident under your acquiring bank's merchant agreement. Notify your payment processor and your acquirer in writing as soon as you confirm the compromise, ideally with timestamps. Second, you will likely need a PCI Forensic Investigator (PFI) engagement, paid by you, to determine scope and dwell time. Third, your annual SAQ A-EP, SAQ D, or ROC will reflect this event for at least the next reporting cycle. Fourth, plan for card-brand fines and reissue costs to flow back to you as a merchant. None of this is meant to scare you out of self-reporting; the penalty for being caught hiding it is materially worse than the penalty for reporting promptly.

Want eyes on your WordPress site this week?

30 minutes with a DoD-cleared engineer. We will run the Funnel Builder check live, audit your installed plugins, review what scripts are running on your checkout, and give you a written read on the gaps and the realistic next steps for a site your size.

Book your free assessment

Prefer to talk first? Email sales@ghosxt.com or call (831) 204-0501.

Call (831) 204-0501 Book free assessment