WordPress site redirecting to spam: a hidden backdoor diverting mobile visitors to a scam page

WordPress Site Redirecting to Spam? Find the Redirect and the Backdoor

If your WordPress site is redirecting to spam, it has been hacked. Malicious code on the server or in the database is sending some of your visitors to a scam page, often only phone users and logged-out guests. The redirect is only the symptom. The backdoor that planted it will put it back unless you find that too.

The short answer

  • A WordPress site redirecting to spam has been hacked; the redirect is a symptom of a backdoor, not a plugin setting.
  • Cloaking hides it from logged-in and desktop users, so test with a mobile user agent via curl and a phone on cellular data.
  • Check .htaccess or server config, home and siteurl in wp_options, theme JavaScript, the database, and plugins including mu-plugins.
  • Remove the backdoor, regenerate salts, change every password, purge every cache, then request a Google Search Console review.

Key takeaways

  • A WordPress site redirecting to spam has been compromised; no legitimate plugin setting does this.
  • Cloaking hides the redirect from logged-in, desktop and direct visitors, so test with a mobile user agent and a phone on cellular data.
  • Check .htaccess or server config, home and siteurl, theme JavaScript, the database, and plugins including mu-plugins, then .user.ini, uploads, DNS and caches.
  • Removing only the visible redirect fails; find the backdoor, rotate every credential, regenerate salts and purge all caches.
  • Request a Google Search Console security review only after the site tests clean from outside.

Why is my WordPress site redirecting to spam?

A WordPress site redirects to spam because malware is sending visitors to a page the attacker profits from. No legitimate plugin setting does this. No real option ships your traffic to fake prize pages, tech-support scams, online casinos, counterfeit pharmacies or crypto “investment” offers. If you see that, you are dealing with a security incident.

The redirect is the result of an earlier break-in. Typical entry points on small sites:

  • an outdated plugin or theme with a published vulnerability
  • a nulled (pirated) plugin or theme
  • stolen FTP, SSH, cPanel or hosting-panel credentials
  • an admin account with a weak or reused password

That code then writes the redirect into one of the places below. It usually also leaves a second component whose only job is to reinstall the redirect if you remove it.

So the cleanup has two passes. First, find the redirect in one of five places:

  1. .htaccess or the web server config
  2. the home and siteurl rows in wp_options
  3. injected JavaScript in theme files
  4. injected content in posts and postmeta
  5. rogue plugins, must-use plugins or themes

Second, find whatever keeps writing it back. If all five look clean, the section on hidden locations further down covers .user.ini, uploads, DNS and caches.

Some infections never redirect a human visitor. The Japanese keyword hack, for example, creates thousands of spam pages that only search engines are meant to see. That hack hides in the same five places.

Why does the redirect only happen on mobile or when I am logged out?

The redirect shows up only on phones, or only for logged-out visitors, because the malware chooses who sees it. This is called cloaking. Before redirecting, the code inspects each request for:

  • User agent: mobile strings such as iPhone, iPad or Android get redirected; desktop browsers do not.
  • Referrer: visitors arriving from Google, Bing or Yahoo get redirected, while people who type your URL see the normal site.
  • Cookies: anyone carrying a wordpress_logged_in_* cookie is skipped. That cookie means you, the admin.
  • Repeat visits: some variants set their own cookie and redirect each visitor only once, so a second test looks clean.

So the owner, logged in on a desktop, sees a normal site, while a customer who taps your Google result on a phone lands on a scam. Attackers build it this way because owners who never see the redirect don’t remove it.

Rule out one exception: if the redirect appears on only one computer or browser and disappears on other devices and networks, suspect adware or a malicious browser extension on that machine.

The 60-second test: take a phone off Wi-Fi, use cellular data, open a private tab, search for your brand and tap your result. The curl checks below do the same thing from a terminal.

WordPress site redirecting to spam on mobile only while the desktop view stays clean, illustrating cloaking
Cloaking shows the scam to phones and search visitors, and the clean site to you.

How do I find where the redirect is coming from?

Confirm the redirect from outside your own browser first. The same test tells you which layer it lives in. From a terminal outside your office network, run:

  • curl -sIL -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)" https://example.com, which prints every hop and its Location header
  • the same command with -e https://www.google.com/ added, to fake a search referrer
  • a scan with Sucuri SiteCheck or VirusTotal as a second opinion

The output narrows the search:

What you see Redirect type Where it usually hides
Your server answers 301 or 302 with a foreign domain in Location Server-side .htaccess, Nginx or IIS config, PHP file, .user.ini, mu-plugin
Your server answers 200, then the browser jumps Client-side JavaScript in theme files, widgets, posts, a meta refresh tag
The domain resolves to an IP you don’t recognize DNS-level Nameservers or A records at the registrar or DNS provider
Entire site and wp-admin go elsewhere, including login Configuration home and siteurl in wp_options, or wp-config.php

Before you delete anything, spend 15 minutes preserving evidence:

  • Take a full backup of files and database, and label it as infected.
  • Download the raw access logs before the host rotates them.
  • Note file modification times.
  • If you put up a maintenance page, have it return a 503 and take it down before you ask Google for a review.

Wiping the site in a panic destroys the record of how the attacker got in. Without that record, the same hole gets reused.

How do I check .htaccess and the home and siteurl settings?

Start here if curl showed a 301 or 302 from your own server, or if wp-admin itself bounces away. Both point to the web server config or two rows in the options table.

.htaccess and the web server config

On Apache, LiteSpeed and OpenLiteSpeed hosting, .htaccess is the most common home for a server-side redirect. It does not appear in the WordPress dashboard, so open it over SFTP, SSH or the cPanel or Plesk File Manager with hidden files shown. Check the site root and every subfolder, including wp-content/uploads and wp-admin.

Compare it against the short default WordPress block. Suspicious additions look like this:

  • mod_rewrite conditions that test HTTP_USER_AGENT for mobile devices or HTTP_REFERER for search engines, followed by a permanent redirect to an outside domain
  • an ErrorDocument 404 line pointing to an external URL, so every broken link becomes a spam hop
  • a php_value auto_prepend_file line that loads a file you never created before every page
  • AddType or AddHandler lines that make .jpg or other image files execute as PHP

Don’t delete the file outright, because that breaks permalinks. Replace it with the default WordPress block and re-save Settings > Permalinks.

Nginx ignores .htaccess completely. Its rules sit in the server block config, which the host or panel usually manages, so ask your host to review it. On Windows IIS hosting, look in web.config.

The home and siteurl rows

home is your public address and siteurl is where WordPress core lives. Change either one and every page follows it, often into a login loop you cannot escape from the dashboard. To get back in, add these lines to wp-config.php above the “stop editing” comment, with your real address:

  • define('WP_HOME','https://example.com');
  • define('WP_SITEURL','https://example.com');

They override the database immediately. Then fix the rows in phpMyAdmin or with wp option update home https://example.com (and the same for siteurl). The table prefix is configurable, so check $table_prefix in wp-config.php for the real name.

On multisite, also check wp_site, wp_blogs and each subsite’s own options table, such as wp_2_options. While wp-config.php is open, look for WP_HOME lines pointing elsewhere, include or require lines loading unfamiliar files, and encoded strings at the top or bottom.

Where do injected scripts and rogue plugins hide?

If curl showed a 200 followed by a jump, the redirect is in code the page outputs: theme files, the database or a plugin. If none of those holds it, check the spots dashboard scanners never read.

Theme files

Injected JavaScript usually sits in header.php, footer.php or functions.php of the active theme, or in enqueued scripts, text widgets and Customizer code fields. Look for a <script src=...> tag loading from an unknown domain, an obfuscated assignment to window.location, a setTimeout wrapper that lets the page flash normally first, or a meta refresh tag.

The PHP that injects it is usually obfuscated with eval, base64_decode, gzinflate or str_rot13, or packed into one enormous line. Don’t hand-edit infected files. Replace the theme folder with a fresh vendor copy, then reapply only child-theme changes you have read yourself.

Posts, postmeta and options

Search wp_posts, wp_postmeta, wp_options and wp_usermeta for script tags and unfamiliar domains. A read-only start: wp db query "SELECT ID, post_title, post_status FROM wp_posts WHERE post_content LIKE '%<script%'". Repeat for iframe and for any domain from your curl output.

  • Posts: sort by date and look for posts you didn’t write, unknown authors, or batches of keyword-stuffed titles.
  • Options: serialized values such as widget_text and theme_mods_* can carry scripts that never appear in a post.
  • Users: run wp user list --role=administrator and remove any admin you can’t account for.
  • Cron: wp cron event list can reveal a job that reinstalls the infection.

To strip injected strings, run wp search-replace with --dry-run first. It handles serialized data correctly; raw SQL replacement does not.

Plugins and must-use plugins

Must-use plugins in wp-content/mu-plugins/ are a favorite home for backdoors: they load on every request and cannot be deactivated from the admin screen. Many sites have no such folder. If yours has one you did not create, read every file, but check your host’s documentation first, since some hosts install legitimate ones.

  • Run wp plugin verify-checksums --all for WordPress.org plugins, and compare premium plugins against a fresh vendor zip.
  • Watch for names that imitate real plugins, or entries with no author and no readme.
  • Remove nulled plugins and themes, and delete everything inactive. Unused code still executes if an attacker calls it directly.

Outside the five places

  • .user.ini: a per-directory PHP config file. An auto_prepend_file line in it runs an attacker file before every PHP request. It applies when PHP runs as CGI or FastCGI, including PHP-FPM, and is cached for user_ini.cache_ttl (300 seconds by default), so a fix can look like it failed for five minutes.
  • PHP in uploads: files such as image.jpg.php in wp-content/uploads are shells. The same pattern was documented in PHP webshells planted after a firewall breach.
  • DNS: if files and database are clean but the domain resolves elsewhere, check nameservers and A records, and secure the registrar login.
  • Caches: Cloudflare or another CDN, Varnish, LiteSpeed Cache, Redis or Memcached can keep serving infected HTML after a successful cleanup. Stale caches are the most common reason a cleaned site “is still redirecting”.

Is deleting the malicious code enough, or will the redirect come back?

No. Deleting only the visible redirect usually brings it back, because the backdoor that wrote it is still in place. A cron job, mu-plugin or .user.ini prepend can rewrite .htaccess within minutes, and a shell in uploads lets the attacker return whenever they like. A real recovery covers all of these steps:

  1. Run wp core verify-checksums, then reinstall core with wp core download --force --skip-content, which replaces core files without re-adding the bundled themes and plugins.
  2. Replace every plugin and theme with a fresh vendor copy.
  3. Regenerate AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY and their salts in wp-config.php with the WordPress.org secret-key service. This invalidates every login cookie.
  4. Change every password: WordPress admins, hosting panel, FTP and SFTP, SSH, the database user, and the email account tied to the registrar.
  5. Clear stored sessions. WordPress keeps them in wp_usermeta under session_tokens, and the profile screen offers “Log Out Everywhere Else”.
  6. Turn on two-factor authentication for every admin.
  7. Purge the browser, plugin, host, CDN and object caches.
  8. Re-test with the mobile curl command and the phone on cellular data.

Should I restore a backup instead?

Restore only if you can show the backup predates the infection, or you reinstall the malware with everything else. To date the break-in, look in the access logs for the first POST requests to files that should not exist, and check modification times. Treat timestamps with caution, because attackers sometimes fake them.

Approach Speed Main risk
Restore a proven-clean backup Fastest Loses content added since; the entry point stays open
Clean in place yourself Slow Missing one backdoor means reinfection
Automated scanner plugin Fast Often misses .user.ini, server config and DNS
Professional malware removal Fast Cost; you still need to rotate credentials

A restore does not patch the plugin, password or panel account the attacker used. The credential, salt, session and two-factor steps above apply whichever route you take.

WordPress spam redirect coming back because the hidden backdoor was not removed
Removing the visible redirect without the backdoor is cutting a weed at the surface.

How do I remove the Google warning and stop the redirect from returning?

Clean the site first, then request a review in Google Search Console under Security & Manual Actions > Security Issues. Google Safe Browsing labels infected sites “Deceptive site ahead” or “Harmful”, and search results may show “This site may be hacked”. These warnings are a result of the infection, not a separate problem.

  • Open the sample URLs Google lists and confirm each one now returns clean content to a mobile user agent.
  • Return a 404 or 410 for spam pages, and resubmit your sitemap.
  • In the review request, state briefly what you found, what you removed, and how you closed the entry point.
  • Submit the same request in Bing Webmaster Tools.

Google gives no fixed timeline. If a review fails, the console lists the URLs that are still flagged.

Then close the door the attacker used. One unpatched bug is enough to restart the cycle, as the WordPress comment vulnerability that can lead to full server control showed.

  • Put a web application firewall in front of the site so exploit attempts are blocked before they reach WordPress.
  • Update core, plugins and themes on a schedule, and delete what you don’t use.
  • Add define('DISALLOW_FILE_EDIT', true); to wp-config.php to disable the built-in file editor.
  • Block PHP execution in wp-content/uploads.
  • Give each person their own account with the lowest role that works, protected by two-factor authentication.
  • Run file integrity monitoring, so a new mu-plugin or .user.ini raises an alert the same day.
  • Keep versioned, off-server backups for several weeks, so a clean one exists when you need it.

Server-side scanning with SiteGuarding antivirus reads the files that dashboard plugins skip, including .user.ini and server config. Ongoing website protection adds the firewall layer, so the next exploit attempt stops at the edge instead of in your .htaccess.

Malicious htaccess rule in a WordPress server config redirecting visitors to a spam domain
One extra rewrite rule in .htaccess can divert every mobile visitor.

FAQ

Why is my WordPress site redirecting to spam?

Malware on the server or in the database is sending visitors to a scam page. Check .htaccess, the home and siteurl options, theme files, posts and rogue plugins, remove both the code and the backdoor, then request a Google review.

Why does my WordPress site redirect only on mobile?

The malware reads the visitor's user agent and redirects only phones and tablets, a technique called cloaking. Many variants also skip logged-in admins and direct visits, so test from a phone on cellular data in a private tab.

Can I just delete the bad lines in .htaccess?

You should replace .htaccess with the default WordPress block, but that alone rarely holds. A cron job, mu-plugin or .user.ini prepend often rewrites it within minutes, so find and remove that component too.

Will the spam redirect come back after cleanup?

It will if the backdoor or the original entry point survives. Reinstall core, plugins and themes from clean copies, regenerate salts, change every password, enable two-factor authentication and purge every cache layer.

How do I remove the Deceptive site ahead warning?

Clean the site, confirm Google's sample URLs return clean content to a mobile user agent, then request a review under Security Issues in Google Search Console. Google gives no fixed timeline.

If the redirect keeps coming back or you would rather not hunt for backdoors yourself, SiteGuarding can clean the site, close the entry point and keep it monitored. See the protection packages.