WPCode Malware: How I Removed a Hidden WPCode Plugin That Was Redirecting a Client’s WordPress Site

wpcode malware
Last Updated on: May 27, 2026

A client messaged me last week with a familiar problem: his WordPress site was redirecting every visitor to a random Cloudflare Pages URL. Sucuri SiteCheck said his site was clean. Wordfence had found nothing. He was about to lose his Monday’s sales.

The culprit was the WPCode plugin — except he had never installed it. Someone else had, then hidden it from his dashboard, then dropped a 7,000-character PHP snippet into it that was redirecting his traffic to scam pages. This is the WPCode malware infection, and in 2026 it’s one of the most common WordPress hacks I see. Here’s the full cleanup, from first symptom to root cause.

Quick Answer

WPCode malware is a WordPress infection where attackers silently install the WPCode (Insert Headers and Footers) plugin on your site, drop a malicious PHP snippet inside it set to run “everywhere,” and then hide the plugin from your WordPress dashboard so you can’t find it. The snippet typically redirects logged-out visitors to spam, scam, or pages.dev URLs, creates hidden admin users, and reinfects after deletion. To find it: count the folders inside wp-content/plugins/ and compare to the All (X) count on your Plugins page. If they don’t match, WPCode is almost always one of the hidden plugins.

What is WPCode malware?

WPCode itself is a legitimate plugin. It’s installed on over 2 million WordPress sites under its full name “WPCode — Insert Headers and Footers + Custom Code Snippets” (folder slug insert-headers-and-footers, main file ihaf.php). It lets developers add PHP, JavaScript, and CSS snippets without editing theme files. There’s nothing wrong with the plugin.

The problem is that WPCode has become the favorite delivery vehicle for a long-running malware campaign that security researchers at GoDaddy named DollyWay. The attackers compromise a site through any available entry point — an outdated plugin, a weak admin password, a vulnerable theme — and then use that initial foothold to do four things:

  • Silently install WPCode if it isn’t already present, fetching the plugin directly from the WordPress.org SVN repository so the source looks legitimate.
  • Create one or more PHP snippets inside WPCode with the execution scope set to “everywhere,” meaning they run on every page load.
  • Hook the WordPress all_plugins filter to hide WPCode from the Plugins page, hide its admin menu, and suppress its update notices.
  • Use those snippets to fetch redirect URLs from a command-and-control server, create hidden admin users on demand via cookie commands, and reinfect the site if any single piece is removed.

If you’ve reached this page because you’ve found WPCode on a site you never installed it on — or because you found a snippet inside WPCode that you didn’t write — this is what you’re looking at. The next sections walk through the actual cleanup I ran last week on a live client site, so you can see what to look for and what to do.

The first symptom: the site was redirecting, but every scanner said it was clean

The client’s first message included a screenshot of his Sucuri SiteCheck report — two green checkmarks, “No Malware Found, Site is not Blacklisted.” He’d also run Wordfence’s free scanner. Same result. And yet every time he opened his homepage in an incognito window, he landed somewhere else.

Sucuri SiteCheck report showing No Malware Found and Site is not Blacklisted on a WordPress site that was actively redirecting visitors due to hidden WPCode malware
Sucuri SiteCheck reporting a clean site while WPCode malware was actively redirecting every logged-out visitor.

Remote scanners are useful but easy to fool. Sucuri’s SiteCheck makes one anonymous request from a generic user agent with no cookies. The WPCode snippet doing the redirect specifically checks for logged-in users, repeat visitors (via a 24-hour transient keyed to IP), and requests to /wp-admin/ — and exits silently if any of those match. SiteCheck’s single anonymous visit doesn’t trigger the payload, so SiteCheck reports clean. The malware is still there.

I opened the homepage with view-source: prefix in an incognito Chrome tab to bypass JavaScript execution and see the raw HTML the server returned:

WordPress page source code showing a malicious meta http-equiv refresh tag pointing to lemon-well-flash.pages.dev as the WPCode malware redirect target
The actual response: a single <meta http-equiv=”refresh”> tag pointing to a Cloudflare Pages subdomain.
<html><head><meta http-equiv="refresh" content="0; url=https://lemon-well-flash.pages.dev/help/?32161731835980&extra_param_1=d8683sl3kl6c73ejm0g0"></head><body></body></html>

The entire page response had been replaced with one meta-refresh tag pointing to a pages.dev URL. Cloudflare Pages is being increasingly abused by malware operators because the SSL certificate is trusted, the latency is low, and the actual scam destination stays one hop removed from the compromised WordPress site. By the time the visitor lands there, the trail back to your domain is fuzzy.

Step 1: Searching the database — and finding nothing

The standard places for a meta-refresh injection are wp_posts.post_content, wp_options (specifically siteurl and home), and the active theme’s header.php. I opened phpMyAdmin and ran a database-wide search for lemon-well-flash, then for pages.dev, then for meta http-equiv:

phpMyAdmin search results showing zero matches across every WordPress database table for the WPCode malware redirect URL lemon-well-flash.pages.dev
Zero matches in any database table — the malicious URL was never stored as plain text.

Zero matches across every table. I also grepped the theme directory and wp-content/uploads for the same strings on the server. Still nothing. That told me the redirect URL wasn’t stored as plain text anywhere — it was being fetched at runtime by code I hadn’t found yet. This is intentional design on the attacker’s part: by storing the destination URL in a dynamically-fetched WordPress option rather than hardcoding it, the attacker can rotate destinations whenever Cloudflare takes down a pages.dev instance, without needing to re-infect anything.

Step 2: The diagnostic that always cracks the case — count the plugins

When the database search and the file grep both come back empty on a redirecting site, I go to the most reliable manual indicator I know: a plugin count comparison. WordPress builds the Plugins page by reading wp-content/plugins/ and applying the all_plugins filter. Malware that hooks all_plugins can hide an entire plugin from the dashboard without touching the disk. The folder always exists. The listing doesn’t.

I logged into File Manager and opened /wp-content/plugins/:

WordPress plugins folder in file manager showing 25 items including the suspicious head-footer-code and insert-headers-and-footers folders for WPCode
25 items on disk: 24 plugins plus the index.php hardening file. Note both head-footer-code and insert-headers-and-footers — a duplicate-purpose pair that’s almost always a malware signature.

Now the WordPress dashboard:

WordPress admin Plugins page showing All (22) count which is two fewer than the actual plugin folder count on disk, indicating hidden WPCode plugin malware
The Plugins page shows All (22). Disk shows 25. Three folders exist that WordPress refuses to admit are there.

Disk says 25 (24 real plugins plus index.php). Dashboard says 22. Two plugins are being actively hidden by something running on the site. This is one of the most reliable malware indicators in WordPress — there is no built-in feature that hides a plugin from the Plugins page. If your folder count doesn’t match the All (X) number, something is hooking all_plugins to lie to you, and that something is almost certainly malicious. I’ve documented the same mismatch pattern in a separate case study where malware mathematically subtracts itself from the user count — same technique, applied to a different list.

Step 3: Identify the hidden WPCode install

I exported a list of every folder in /wp-content/plugins/ and compared it line-by-line to the dashboard. Two folders had no match:

  • head-footer-code — a plausible-sounding fake plugin name designed to blend in. Deleting it didn’t stop the redirect. This was the decoy.
  • insert-headers-and-footers — the legitimate folder name for the WPCode plugin. This client had never installed WPCode. The plugin’s menu wasn’t visible. Its entry was filtered out of all_plugins. Yet the entire plugin was sitting in the plugins directory, active and running on every page load.
Hidden insert-headers-and-footers plugin folder contents showing ihaf.php and complete WPCode plugin structure used as a malware host on a hacked WordPress site
The insert-headers-and-footers folder is structurally identical to a clean WPCode install. The attacker didn’t ship a fake plugin — they installed the real one and used it as a payload host.

This is the part that throws most site owners off. The plugin itself isn’t fake. The files inside it aren’t modified. If you scanned the plugin directory with Wordfence after the malware was active, Wordfence would see “WPCode 2.2.1, official version, file checksums match” and move on. The malicious payload isn’t in the plugin’s files — it’s in the database, as a snippet entry that WPCode loads and executes itself.

Step 4: A bonus discovery — the “innocent” Code Snippets entry

Before touching WPCode, I noticed the client also had the unrelated Code Snippets plugin installed and active. Different plugin, different developer, different database table ({prefix}_snippets). I queried that table directly and found an active snippet I didn’t expect:

Code Snippets plugin database table showing a Disable admin bar snippet using show_admin_bar false that was planted by malware to obscure debugging
An innocent-looking show_admin_bar(false) snippet. In isolation it’s harmless. In context, it was the attacker hiding their tracks.
add_action( 'wp', function () {
    if ( ! current_user_can( 'manage_options' ) ) {
        show_admin_bar( false );
    }
} );

Read in isolation, that code is harmless — it hides the WordPress admin bar from non-admin users. Plenty of legitimate sites do this. But the client confirmed he had never written it, and no developer had touched the site in over a year. The snippet’s purpose wasn’t functional — it was obscuration. If the owner ever logged in as a lower-privilege user to debug, the admin bar would be missing, which makes the symptoms easier to dismiss as “something with my theme.” It’s a tiny piece of social engineering hidden inside legitimate-looking PHP. Attackers think about ergonomics. They make investigation boring.

I deleted the snippet first. That made nothing visibly better, but it cleared the way for the next step.

Step 5: Unhide WPCode and find the real payload

I went into the WPCode plugin folder via SFTP and renamed it temporarily — that breaks the active hook that filters WPCode out of the plugin list. After refreshing the dashboard, the plugin count jumped from 22 to 23. I renamed the folder back, reactivated the plugin, and the WPCode admin menu finally appeared.

WordPress sidebar showing Code Snippets and WPCode admin menus reappearing after the hiding filter from the malware was neutralized
With the hiding filter neutralized, the WPCode menu reappeared in the sidebar.

Inside WPCode’s snippet editor, one entry was waiting: an “Untitled Snippet” set to PHP, location “everywhere,” auto-insert priority 10. The code was 7,893 bytes long, fully readable PHP, no obfuscation needed.

WPCode plugin Edit Snippet screen showing the malicious PHP payload starting with _WP_WEBSITE constant definition and _WP_PWSA password hash
The actual payload inside WPCode: an Untitled Snippet, set to load everywhere, with the victim’s domain hardcoded as _WP_WEBSITE.

Here’s what the snippet actually does, broken into the five things it accomplishes:

  • Disables every WordPress cache layer for itself. The first ten lines fire add_filter calls against SiteGround SG Optimizer, Autoptimize, WP Rocket, W3 Total Cache, LiteSpeed, and the WordPress built-in cache. The attacker wants the redirect to fire on every visitor in real time. Cached HTML would expose the meta refresh tag to administrators reviewing their site.
  • Hides itself and the plugin from administrators. If the current user can edit pages, the snippet hooks admin_head, all_plugins, and the update_plugins transient to make WPCode (and the decoy head-footer-code) invisible. That’s the filter that was hiding the three folders from the dashboard count.
  • Provides a cookie-based remote admin endpoint. The function _gcookie() checks for a base64-encoded cookie named pw. If the value matches the hardcoded hash 65cee9c9c1d0f71b937bcf85ebff913f, the attacker can pass additional cookies (u, p, e) and silently call wp_create_user() with administrator role — no login form, no audit log entry, no notification email.
  • Stores the redirect destinations as a WordPress option, populated remotely. This is why my database search came up empty. The redirect URLs come from get_option('l'), which the attacker writes to via the same cookie command channel (case 'sl'). When Cloudflare takes down one pages.dev URL, the attacker pushes a new one to every infected site — no re-infection needed.
  • Conditional redirect for logged-out visitors only. The _red() function fires on init. It exits immediately for logged-in users, requests to /wp-admin/, requests to wp-login.php, and visitors who’ve already been redirected in the last 24 hours (tracked by transient exp keyed on IP). The site owner viewing their own dashboard never sees the redirect. The first visitor of the day from any given IP gets hit once and then doesn’t get hit again for 24 hours — which is why owners always say “but when I check it myself, it’s fine.”

This architecture matches the DollyWay v3 campaign documented by GoDaddy security researcher Denis Sinegubko. The campaign has been active since 2016, has compromised more than 20,000 WordPress sites, and currently generates around 10 million fraudulent ad impressions per month routed through the VexTrio and LosPollos affiliate networks. The technical details vary site to site, but the WPCode-as-payload-host pattern is now its signature.

How to remove WPCode malware (the order that actually works)

Removal order matters here. DollyWay injects copies of its payload into multiple active plugins and reinfects on every page load. Delete the visible snippet first and the malware regenerates it within seconds. The working sequence on this client’s site was:

  1. Take the site offline behind a maintenance page before touching anything. This stops further redirects and prevents the reinfection cycle from firing during cleanup.
  2. Delete the decoy Code Snippets entry from the {prefix}_snippets table (the show_admin_bar one, if you have it).
  3. Delete the WPCode snippet from the database directly. Don’t use the WPCode interface — the row is in {prefix}_wpcode or as serialized data inside a {prefix}_options row, depending on plugin version. Delete the row entirely. Emptying the value lets WPCode regenerate it from cache.
  4. Delete the orphan WordPress options l, d, and the transient exp from the options table. These are the attacker’s command-and-control storage keys.
  5. Delete the entire insert-headers-and-footers folder from /wp-content/plugins/. If you legitimately use WPCode, reinstall it fresh from WordPress.org afterward. Delete the head-footer-code decoy folder too.
  6. Audit every other active plugin’s PHP files for the same payload signature. Grep for _WP_WEBSITE, _WP_PWSA, and the _red() function name across the entire wp-content directory. DollyWay scatters copies into multiple plugins so cleanup that stops at the snippet leaves the site reinfecting on the next page load. My guide on why WordPress malware keeps coming back covers the broader reinfection pattern.
  7. Audit wp_users for usernames that look like 32-character hex strings, or any administrator account the owner doesn’t recognize. DollyWay creates these proactively. See my detailed guide on finding and removing hidden WordPress admin users.
  8. Rotate every credential — WordPress admin, hosting, FTP/SFTP, database user, and the WordPress secret keys in wp-config.php. The C2 channel is keyed to a hardcoded password hash, so rotating the hash makes any future cookie command useless.
  9. Run a Wordfence high-sensitivity scan after the hiding filter is gone. Wordfence will now actually catch the residual plugin-level injections it missed when the hide filter was suppressing the WPCode menu and dashboard notices.

For the complete systematic cleanup process across files, database, and post-cleanup hardening, see my WordPress malware removal expert guide.

Three things this case teaches WordPress site owners

  • A clean SiteCheck report doesn’t mean a clean site. Remote scanners visit your homepage once, anonymously, with no cookies. WPCode malware is built to evade exactly that visit. If you’re seeing redirects with your own eyes and your scanner says clean, trust your eyes.
  • Plugin count mismatches are one of the most reliable manual indicators of compromise. No legitimate WordPress feature hides plugins from the dashboard. Anything beyond a single-folder difference between /wp-content/plugins/ and the All (X) count means something is hooking all_plugins to hide a plugin from you.
  • Don’t assume a “harmless” snippet is actually harmless. The show_admin_bar(false) code wasn’t a backdoor — it didn’t redirect anyone, didn’t create users, didn’t talk to a C2 server. It was planted to make your debugging harder. Investigate every snippet you didn’t personally write.

When to bring in help

I’ve cleaned more than 4,500 hacked WordPress sites at this point, and the WPCode-malware cleanups that come back to bite owners are almost always the ones where the visible snippet got removed but the persistence mechanism didn’t. With this infection family the snippet is the symptom, not the disease. The disease is the injection sitting inside every active plugin, the hidden admin account waiting for a password reset, and the WordPress option storing the next C2 endpoint.

If you’ve found WPCode on your site that you never installed, or you’ve found a snippet inside WPCode that you didn’t create, and you want a guaranteed cleanup with persistence audit and 30-day reinfection guarantee, my WordPress malware removal service handles the full job. If you’re already stuck in a reinfection loop, the regenerating malware case study covers the persistence side in depth. Or just hire me directly and I’ll take a look at your site.

FAQ

I never installed WPCode on my WordPress site — why is it there?

An attacker installed it. WPCode (also known by its folder name insert-headers-and-footers) is one of the most popular targets for the DollyWay malware campaign because it’s a legitimate, widely-used plugin that won’t trigger security alerts and because it can execute arbitrary PHP through its snippet feature. The malware silently installs WPCode through a compromised plugin or weak admin password, then hides it from your dashboard so you don’t notice.

Why doesn’t WPCode show up in my WordPress dashboard even though the folder is in the plugins directory?

Because the malware is actively hiding it. The malicious snippet inside WPCode hooks WordPress’s all_plugins filter and unsets the WPCode entry before the Plugins page is rendered. It also injects CSS that hides the WPCode admin menu via display: none. The plugin is loading and executing every page request — you just can’t see it. Renaming the plugin folder via FTP breaks the hiding hook and makes it visible again.

I found a snippet in WPCode that I didn’t add. Should I just delete it?

Deleting the visible snippet is necessary but not sufficient. The same payload is usually injected into other active plugins and reinfects on every page load. You also need to delete the related WordPress options (l, d) that store the C2 destination, audit your admin user list for hex-string usernames, and grep every plugin file for the _WP_WEBSITE constant. If you’re not comfortable doing all of that, get professional help — partial cleanup is worse than no cleanup because it teaches you the site is “fixed” when it isn’t.

WPCode keeps reinstalling itself after I delete it. How do I make it stop?

The reinfection is being driven by malicious code inside one or more of your other plugins, or by a hidden admin account that the malware uses to reinstall WPCode via the standard plugin installer. Grep your entire wp-content/plugins/ directory for insert-headers-and-footers, _WP_WEBSITE, and wp_create_user. Audit your wp_users table directly via phpMyAdmin (the admin Users page may be lying to you the same way the Plugins page was). Until you remove the persistence mechanism, deleting WPCode alone will never stick.

Is WPCode itself dangerous? Should I uninstall it?

No, WPCode is a legitimate plugin with over 2 million active installs. The plugin’s code is fine. The problem is that attackers use it as a delivery mechanism for malicious snippets. If you actively use WPCode for legitimate snippets, audit your snippet list and delete anything you didn’t personally create. If you don’t use it, uninstalling is the safer choice — it removes one of the most common payload hosts attackers reach for.

Why does my site only redirect sometimes and not every time I visit?

The malware sets a 24-hour WordPress transient keyed to your IP address. Once you’ve been redirected, you won’t be redirected again from the same IP for 24 hours. That’s why owners often can’t reproduce the issue on the same browser they first saw it on. Test from your phone on cellular data, a new incognito window, or a different network entirely.


Last updated: November 2025 by MD Pabel, WordPress Security Specialist — 4,500+ hacked WordPress sites cleaned. Found WPCode malware on your site? Send me a message and I’ll take a look.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *