How to Check If Your WordPress Site Is Hacked - 5 Signs to Look For - CloudyWP
Luke Anderson WordPress

How to Check If Your WordPress Site Is Hacked – 5 Signs to Look For – CloudyWP

Our WordPress site looks perfectly normal. The homepage loads. The blog posts are there. No popups, no warnings, nothing obviously wrong. So everything’s fine, right? Not necessarily. The most common type of WordPress compromise in 2026 isn’t dramatic, it’s silent. Attackers inject hidden links into your pages that only Google can see, slowly poisoning your search rankings over months until your traffic collapses and Google flags your site as “hacked.” By the time you notice, the damage is done. The good news? You can run five simple checks right now, without installing a single plugin — and find out for sure in under 5 minutes. Here’s exactly how to do it.

This is the fastest check anyone can do. No terminal, no tools, no technical background, just your web browser. It catches the most common type of WordPress hack: hidden SEO spam injection.

You’re going to view the raw HTML of your homepage and search for telltale signs of hidden links. Hackers hide spam content using CSS tricks like display:none and opacity:0, invisible to you, but fully readable by Google. If you find suspicious external links wrapped in these styles, your site is compromised.

Found hidden links in your source? That’s a confirmed injection, not a false alarm. We do WordPress malware removal from $299 — cleaned, restored and hardened, usually within 24 hours.

Get it cleaned →
  1. Open your WordPress site’s homepage in any browser
  2. Right-click anywhere on the page → click “View Page Source” (or press Ctrl+U on Windows, Cmd+Option+U on Mac)
  3. A new tab opens showing the raw HTML of your page
  4. Press Ctrl+F (or Cmd+F) to open the search bar
  5. Search for each of these terms, one by one:
    • display:none
    • opacity:0
    • visibility:hidden
    • text-indent:-9999

Like in this image, how ever here content is site’s own code so it is fine.

href="https://cheap-pharmacy-online.example/buy-viagra"
href="https://canadian-pills-discount.example/cialis-generic"
href="https://no-prescription-meds.example/order-now"
href="https://genericrx-store.example/levitra"
href="https://best-casino-2026.example/play-now"
href="https://online-poker-bonus.example/signup"
href="https://slots-jackpot-huge.example/spin"
href="https://sports-betting-aus.example/register"
href="https://crypto-casino-no-kyc.example/"
href="https://quick-cash-now.example/apply"
href="https://payday-advance-fast.example/get-money"
href="https://no-credit-check-loans.example/instant"
href="https://debt-consolidation-help.example/"
href="https://replica-watches-cheap.example/rolex"
href="https://designer-bags-copy.example/louis-vuitton"
href="https://fake-sneakers-store.example/jordan"
href="https://imitation-jewelry-sale.example/"
href="https://hot-singles-near-you.example/meet"
href="https://adult-dating-tonight.example/signup"
href="https://escort-services-local.example/"
href="https://webcam-girls-live.example/free"
href="https://buy-backlinks-cheap.example/packages"
href="https://seo-services-instant.example/rank-1"
href="https://google-ranking-boost.example/"
href="https://link-building-pro.example/order"
href="https://crypto-millionaire-2026.example/invest"
href="https://bitcoin-doubler-trusted.example/"
href="https://forex-signals-vip.example/join"
href="https://nft-flip-profit.example/"

Keywords to look for:

Suspicious Domain Endings

By using curl with a Googlebot User-Agent, you see exactly what Google sees

curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1)" https://yourdomain.com/ | grep -oE 'href="https?://[^"]+"' | grep -v "https://yourdomain.com/" | sort -u

see hidden content on page

curl -s https://yourdomain.com/ | grep -oE 'style="[^"]*(display:\s*none|opacity:\s*0|visibility:\s*hidden|text-indent:\s*-9999)[^"]*"' | head -20

use these commands

Step 1 — Download the page as a browser:

curl -s -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0.0.0" https://yourdomain.com/ > /tmp/browser.html

Step 2 — Download the page as Googlebot:

curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://yourdomain.com/ > /tmp/googlebot.html

This is what a clean result looks like:

Now This is what a hacked result looks like:

12,453 /tmp/browser.html
38,901 /tmp/googlebot.html
51,354 total

If Both files are exactly (or nearly) the same size. Your server is sending the same content to humans and Google. No cloaking. You’re safe.

Here is the query you can run in your database

FOR “WP_POSTS” TABLE

SELECT ID, post_title, post_type
FROM wp_posts
WHERE post_status = 'publish'
AND post_type IN ('post', 'page')
AND (
  -- High-confidence spam keywords (matched as whole words only)
  -- Pharmacy spam
  post_content REGEXP '[^a-zA-Z](viagra|cialis|levitra|kamagra|tadalafil|sildenafil|vardenafil)[^a-zA-Z]'
  
  -- Compound spam phrases (almost never appear in legitimate content)
  OR post_content REGEXP '[^a-zA-Z](payday-loan|cash-advance|no-credit-check|debt-consolidation|payday-cash|quick-cash-loan)[^a-zA-Z]'
  OR post_content REGEXP '[^a-zA-Z](replica-watches|replica-rolex|fake-rolex|replica-gucci|replica-louis-vuitton|knockoff-bags)[^a-zA-Z]'
  OR post_content REGEXP '[^a-zA-Z](crypto-doubler|bitcoin-doubler|crypto-millionaire|forex-signals|nft-flip|crypto-mining-cloud)[^a-zA-Z]'
  OR post_content REGEXP '[^a-zA-Z](buy-backlinks|cheap-backlinks|backlink-packages|seo-services-cheap|google-ranking-boost)[^a-zA-Z]'
  OR post_content REGEXP '[^a-zA-Z](adult-cam|webcam-girls|escort-service|hookup-tonight|sex-chat)[^a-zA-Z]'
  
  -- Standalone spam words
  OR post_content REGEXP '[^a-zA-Z](porn|xxx|pornhub|onlyfans-leak)[^a-zA-Z]'
  
  -- Structural pattern 1: Hidden div/span/p immediately followed by an anchor tag
  OR post_content REGEXP '<(div|span|p)[^>]*style=[^>]*(display:[[:space:]]*none|opacity:[[:space:]]*0|visibility:[[:space:]]*hidden|text-indent:[[:space:]]*-9999px|position:[[:space:]]*absolute[^>]*left:[[:space:]]*-9999)[^>]*>[[:space:]]*<a[[:space:]]'
  
  -- Structural pattern 2: Anchor tag with hidden CSS applied directly
  OR post_content REGEXP '<a[^>]*style=[^>]*(display:[[:space:]]*none|opacity:[[:space:]]*0|visibility:[[:space:]]*hidden)[^>]*href'
  
  -- Structural pattern 3: Links to known spam top-level domains
  OR post_content LIKE '%href="%.ru/%'
  OR post_content LIKE '%href="%.cn/%'
  OR post_content LIKE '%href="%.tk/%'
  OR post_content LIKE '%href="%.ml/%'
  OR post_content LIKE '%href="%.ga/%'
  OR post_content LIKE '%href="%.cf/%'
  
  -- Structural pattern 4: Obfuscated PHP/JS injection markers
  OR post_content LIKE '%base64_decode%'
  OR post_content LIKE '%eval(%'
  OR post_content LIKE '%<script%document.write%'
);

FOR “POST_META” TABLE

SELECT post_id, meta_key, LEFT(meta_value, 200) AS preview
FROM wp_postmeta
WHERE (
  -- High-confidence spam keywords (with space/punctuation boundaries)
  meta_value LIKE '% viagra %'
  OR meta_value LIKE '% viagra.%'
  OR meta_value LIKE '%>viagra<%'
  OR meta_value LIKE '%"viagra"%'
  OR meta_value LIKE '% cialis %'
  OR meta_value LIKE '%>cialis<%'
  OR meta_value LIKE '%"cialis"%'
  OR meta_value LIKE '% levitra %'
  OR meta_value LIKE '% kamagra %'
  
  -- Compound spam phrases (distinctive — no false-positive risk)
  OR meta_value LIKE '%payday-loan%'
  OR meta_value LIKE '%cash-advance%'
  OR meta_value LIKE '%replica-watches%'
  OR meta_value LIKE '%replica-rolex%'
  OR meta_value LIKE '%crypto-doubler%'
  OR meta_value LIKE '%bitcoin-doubler%'
  OR meta_value LIKE '%forex-signals%'
  OR meta_value LIKE '%buy-backlinks%'
  OR meta_value LIKE '%cheap-backlinks%'
  OR meta_value LIKE '%escort-service%'
  OR meta_value LIKE '%adult-cam%'
  
  -- Hidden CSS patterns
  OR meta_value LIKE '%style="display:none%'
  OR meta_value LIKE '%style="opacity:0%'
  OR meta_value LIKE '%style="visibility:hidden%'
  
  -- Spam TLD links
  OR meta_value LIKE '%href="%.ru/%'
  OR meta_value LIKE '%href="%.cn/%'
  OR meta_value LIKE '%href="%.tk/%'
  OR meta_value LIKE '%href="%.ml/%'
  
  -- PHP/JS obfuscation markers
  OR meta_value LIKE '%base64_decode(%'
  OR meta_value LIKE '%eval($_%'
)
LIMIT 50;

FOR “WP_OPTIONS” TABLE

SELECT option_name, LEFT(option_value, 200) AS preview, autoload
FROM wp_options
WHERE (
  option_value LIKE '% viagra %'
  OR option_value LIKE '%>viagra<%'
  OR option_value LIKE '% cialis %'
  OR option_value LIKE '%>cialis<%'
  OR option_value LIKE '% levitra %'
  OR option_value LIKE '%payday-loan%'
  OR option_value LIKE '%cash-advance%'
  OR option_value LIKE '%replica-watches%'
  OR option_value LIKE '%crypto-doubler%'
  OR option_value LIKE '%bitcoin-doubler%'
  OR option_value LIKE '%forex-signals%'
  OR option_value LIKE '%buy-backlinks%'
  OR option_value LIKE '%escort-service%'
  OR option_value LIKE '%style="display:none%'
  OR option_value LIKE '%style="opacity:0%'
  OR option_value LIKE '%href="%.ru/%'
  OR option_value LIKE '%href="%.tk/%'
  OR option_value LIKE '%href="%.ml/%'
  OR option_value LIKE '%base64_decode(%'
  OR option_value LIKE '%eval($_%'
  OR option_value LIKE '%<script%document.write%'
)
LIMIT 50;

the code above run it in your database SQL, if it shows results check that content carefully there is chance that database is hacked.

If your table names in WordPress database has different prefix than “wp_” adjust queries accordingly before running.

For this part i advise you to take your website backup to local-host as we need to use WP CLI.

How we can use WP CLI IN SERVER OR C PANEL thats for another day.

user localwp by flywheel and add you website there, Don’t know how to do it. I will add separate guide for it. Here is the interface what you will see once you have your website up in this tool

Here click on “Site shell”, now new window will open

Main thing is WP-CLI is installed and 2nd important thing, in image site in local called “localbusiness”, you need to put your website files in there “name” can be anything. because your files are in local so cli will work on your site.

NOW IMPORTANT COMMANDS

wp core verify-checksums

this commands checks WordPress files with official WordPress site. and sees any changes in the files. This will show if any modification is there

If all good you will see

wp plugin verify-checksums --all

Now this Compares each installed plugin against its official WordPress.org version. If any modifications are there you will be alerted.

Any verified and skipped plugins will be displayed, as it only verifies to WordPress.org

IMPORTANT COMMANDS

dir /s /b wp-content\uploads\*.php

Checks for PHP files in upload directory

forfiles /p . /s /m *.php /d -30 /c "cmd /c echo @path"

/p . starts in the current directory
/s searches all subdirectories
/m *.php matches only PHP files
/d -30 means "files modified more recently than 30 days ago"
/c "cmd /c echo @path" prints the full path of each match

COMMAND FOR MALWARE DETECTION

findstr /s /i /n /c:"eval(base64_decode" /c:"eval(gzinflate(" /c:"eval(str_rot13" /c:"eval(gzuncompress" /c:"@eval($_POST" /c:"@eval($_GET" /c:"@eval($_REQUEST" /c:"@eval($_COOKIE" /c:"@eval($_SERVER" /c:"@assert($_POST" /c:"@assert($_GET" /c:"@assert($_REQUEST" /c:"create_function(" /c:"eval(stripslashes(" /c:"eval(strrev(" /c:"eval(pack(" /c:"FilesMan" /c:"WSO Shell" /c:"c99shell" /c:"r57shell" *.php

FOR LINUX

grep -rEn --include="*.php" "eval\(base64_decode|eval\(gzinflate\(|eval\(str_rot13|eval\(gzuncompress|@eval\(\\\$_(POST|GET|REQUEST|COOKIE|SERVER)|@assert\(\\\$_(POST|GET|REQUEST)|create_function\(|eval\(stripslashes\(|eval\(strrev\(|eval\(pack\(|FilesMan|WSO Shell|c99shell|r57shell" .
Queries returned rows?

Don’t clean the database by hand.

Deleting injected rows without finding the backdoor that wrote them means reinfection within days. We trace the entry point, clean every affected file and table, and submit your site for Google review to lift the “this site may be hacked” warning.

See how the cleanup works →

From $299 fixed · Content preserved · Melbourne-based, Australia-wide


Discussion

Be the first to comment

Leave a comment

Get a quote