Skip to content

SecurityComplete guide · 8 parts

Hacked website? The signs, how to confirm it, and how to recover

A hacked website rarely looks hacked to its owner. Learn the signs, see your site the way Google does, confirm what you find and clean it so the spam does not come back.

getReport teamUpdated 26 Sept 202623 min read

A hacked website usually still looks normal to its owner. Most hacks today are built to stay hidden: they show spam only to Googlebot, redirect only visitors who arrive from a Google result, or add pages you never open, and serve the ordinary page to everyone who types the address. So the first signs are strange titles in Google, a warning label, a traffic drop or a customer's complaint, not anything on your screen. This guide is the map: the signs, how to see your site the way Google sees it, the common kinds of hack, and the cleanup order that keeps the spam from coming back. Checking takes five minutes; a cleanup takes an afternoon to a day.

Quick answer

  • Look from the outside. Run the hacked site checker. It fetches the page as a normal visitor, as Googlebot and as a visitor from Google, and compares the three copies.
  • Read the differences. Pharma, casino or loan links, text in a script you do not publish in, or a redirect to a site you do not own mean an injection.
  • Confirm it by hand in Search Console (URL Inspection), with a site: search and with curl.
  • Clean in order: freeze the evidence, update, find and remove the injection and the backdoor, reinstall code from clean sources, change every password and key.
  • Only then request a review under Security issues in Search Console. Google's help pages say a review takes a few days to a few weeks.
  • On WordPress, follow recovering a hacked WordPress site, step by step for the full command-line walkthrough.

What does a hacked website look like?

These are the signs owners actually report, roughly in the order they notice them:

  • Google results for the site show titles about Viagra, casinos or loans, or whole lines of Japanese text, often on URLs the site never had.
  • A result carries the label "This site may be hacked", or Chrome shows a red "Deceptive site ahead" or "Dangerous site" page.
  • Customers say that clicking the site in Google took them to a casino, a pharmacy or a "you won a phone" page.
  • Organic traffic drops sharply within a few days, while direct traffic looks normal.
  • Search Console emails you about security issues, or lists an owner you never added under Settings → Users and permissions.
  • Your host suspends the account for sending spam or using too much CPU, or your mail starts bouncing because the server's address is on a blocklist.

The cost is rankings first, then trust. Google demotes or labels hacked pages, and if the attacker also serves malware or phishing, browsers warn every visitor before the page loads. The attacker's goal is usually your domain's reputation: their links on your pages help their own sites rank, and your visitors become their traffic.

Why your own browser shows a clean page

The injected code checks who is asking before it answers. User-agent cloaking looks for "Googlebot" in the request and serves spam only then. Referrer cloaking looks at where the visitor came from: arriving from google.com triggers a redirect, typing the address does not. Many injections also skip logged-in WordPress users, or fire once per visitor and set a cookie. The one person guaranteed never to see it is the owner checking the home page from a bookmark.

Cloaking: why Google sees a different site

Cloaking means showing search engines different content from what people see. Google's spam policies name it as a violation, whoever does it. On a hacked site it is the attacker's main tool, because it lets the spam run for months before anyone notices.

The simplest versions compare the User-Agent header with a list of bot names. Better ones check the visitor's IP address against Google's published crawler ranges, so only the real Googlebot gets the spam. That difference matters for testing: a fetch that only pretends to be Googlebot catches the first kind, and only Google's own fetch in Search Console catches the second.

What is cloaking in SEO? explains every signal cloaking code reads (user agent, IP, referrer, cookie, device), what is not cloaking, such as mobile layouts, paywalls and A/B tests, and three ways to see exactly what Googlebot sees, from URL Inspection to a curl diff.

How to check if your website is hacked

The checker fetches the page three times: with our own user agent as a normal visit, with Googlebot's user agent, and with a Chrome user agent plus a Referer header from https://www.google.com/. It does not run JavaScript; it compares the HTML each fetch returns.

The fetch comparison table: columns for normal visitor, Googlebot and visitor from Google; rows for response, final URL, visible words, words not on the visitor page, links, hidden links, spam vocabulary, text in another script and referrer redirect script, with the differing cells highlighted
On a cloaked page the Googlebot column carries words, links and spam vocabulary the visitor column does not.

What each row compares:

  • Words not on the visitor page. The most frequent words of each copy are compared. When at least 30% of the Googlebot or Google-visitor copy is missing from the visitor copy and at least 20 words are new, the cloaking finding fires.
  • Spam vocabulary. A fixed list of 36 words and phrases that injections use and legitimate navigation almost never does: pharma (viagra, cialis, tramadol), gambling (casino, slots, betting), payday loans, replica goods, essay mills, adult terms and crypto giveaways. Matched as whole words in visible text, hidden text and link URLs.
  • Hidden links. Links to other sites inside an element hidden with the hidden attribute, aria-hidden="true" or an inline style: display:none, visibility:hidden, zero opacity or font size, or a position far off-screen.
  • Text in another script. Runs of Chinese, Japanese, Korean or Cyrillic characters on a page whose lang says it is in another language. This is how the Japanese keyword hack shows up.
  • Referrer redirect script. An inline script that reads document.referrer, looks for Google, Bing or Yahoo, and changes location.
  • Final URL. A redirect to another host that happens for one fetch and not the others.

The panel is headed "differences are evidence, not a verdict", and it means it. A sports blog that links to a betting guide, a booking page with "free slots", a site that serves a lighter page to bots: all of them match. You know which links and words are yours.

The ways in, checked passively

The same run looks at the usual ways in, using only what the page itself reveals and a few fixed addresses. It never guesses plugin paths, tries passwords or scans for hidden files.

  • An out-of-date CMS, from the version the page's generator tag announces. Reading the generator tag explains what it can and cannot tell.
  • Plugins closed or abandoned on wordpress.org, for the plugins whose files the page loads. See abandoned and closed plugins.
  • A readable .env or .git: two fixed requests, for /.env and /.git/HEAD. The finding says which of the two answered, never what is in the file.
  • Open directory listings in up to three folders the page's own images, scripts and styles come from. Directory listings and exposed files covers both of these.

A finding that could help an attacker follows one rule on getReport: the report says that the problem exists, never what it exposes. That is why the .env finding names the file but never shows its contents. Checks for more sensitive WordPress files, such as an exposed debug.log, are planned; they will show yes or no to everyone and the details only to an owner who has verified the site.

Google's own verdict comes from Safe Browsing: the Web Risk finding carries it once the lookup runs in your report. Until then, look the domain up on the Safe Browsing site status page in Google's Transparency Report.

Watch out

"No differences" covers this URL, fetched from our servers, once. It cannot see injections on other pages, spam loaded by external JavaScript, links hidden by a stylesheet class, or code that checks Google's real IP addresses. If Google shows spam for your site, trust Google and test the exact URLs it lists.

Confirm it by hand

Open the spam links finding first. Each line names the fetch that received the link, the anchor text and the target.

The spam links finding opened: pharma and casino links, each marked "googlebot only", with anchor text and the external URL they point to
Links that only Googlebot receives are listed with their anchor text and target.

Write down the domains the links point to and any words that stand out. They are your search terms for the cleanup.

Search Console. URL Inspection → enter the URL → Test live URL → View tested page → HTML. That is the page as Googlebot fetches it, from Google's own addresses, so it also catches IP-based cloaking. View crawled page shows the copy Google has indexed. Search the HTML for the spam domain. Then open Security & Manual Actions → Security issues: if Google has found the hack, it lists the issue type and sample URLs.

Google itself. Search site:example.com viagra, site:example.com casino or just site:example.com and scroll. Pages you never created, especially with Japanese titles, are generated by the hack.

curl, to compare the copies yourself:

Shell
# Normal visitor and Googlebot, saved to two files
curl -s -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" https://example.com/ -o visitor.html
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://example.com/ -o googlebot.html

# Links only one copy has
diff <(grep -o 'href="[^"]*"' visitor.html | sort -u) <(grep -o 'href="[^"]*"' googlebot.html | sort -u)

# A visitor from Google: a Location header to another site is a server-side redirect
curl -sI -e "https://www.google.com/" -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" https://example.com/

A JavaScript redirect only fires in a browser: open a private window, search for your site on Google and click the result. Try it on a phone too, because some redirects fire only for mobile user agents.

The common kinds of website hack

Most hacks on small sites fall into a handful of patterns. Knowing which one you have tells you where the code hides and which guide to follow.

The most common hack is not visible at all. The attacker adds links and text for pharmacies, casinos, payday loans or replica goods, hides them from visitors with CSS or serves them only to Googlebot, and uses your domain's reputation to push their pages up. Some injections go further and generate thousands of doorway pages, or rewrite your titles and descriptions only in Google's copy.

Pharma and casino spam injections: how they hide walks through the six shapes these injections take, which getReport finding shows each one, where the loader lives in WordPress, Joomla, Drupal and custom PHP, and a one-hour detection routine with the grep and database queries to run.

The Japanese keyword hack

This one creates new pages rather than editing yours: thousands of URLs with Japanese titles selling counterfeit goods, often added to your sitemap. The attacker frequently verifies themselves as an owner in your Search Console so they can submit those pages, which is why an unknown owner is such a strong sign.

The Japanese keyword hack: symptoms, where it hides, how to recover covers taking Search Console back, finding the generator that builds the pages, deleting them and getting them out of Google's index.

Redirect hacks

Here visitors are sent to a scam, adult or casino site, often only when they arrive from a search engine, only on mobile, or only once per visitor. The redirect sits in .htaccess or the nginx config, in PHP files such as index.php or wp-config.php, in the database (the siteurl and home options, or a script injected into posts), or in an inline script that reads document.referrer.

A typical injected .htaccess rule looks like this:

Apache
# Injected: sends visitors from search engines elsewhere
RewriteCond %{HTTP_REFERER} (google|bing|yahoo) [NC]
RewriteRule ^(.*)$ https://spam-domain.example/ [R=302,L]

The checker's conditional redirect finding catches the server-side and inline-script versions.

WordPress hacked redirect: why your site sends visitors to spam shows how to reproduce a redirect that hides from you (from Google, on a phone, once per visitor), how to tell a server redirect from a JavaScript one in the Network tab, and the commands that find the code in .htaccess, PHP, script files, the database and cron.

Malware, phishing and a Safe Browsing flag

When the attacker uses your site to serve malware, host a phishing page or push unwanted downloads, Google's Safe Browsing lists it. Chrome, Firefox and Safari then show a full-page red warning before your site loads, and almost every visitor turns back.

Flagged by Google Safe Browsing: what it means and how to clear it shows how to confirm the flag, read Google's sample URLs, find the cause, clean in the right order and request the review. It also covers what to do if you believe the flag is a false positive.

The "This site may be hacked" label

Google adds this line under a search result when it believes a third party has changed the site's content, usually because of spam injections or generated pages. It is not the same as the red Safe Browsing warning: visitors can still click through, but many will not. Search Console's Security issues report usually names the hack type and lists sample URLs.

This site may be hacked: why Google shows it and how to remove it explains the three hack types behind the label, what to do when the Security issues report is empty, how to handle the spam URLs, and how to write a review request that succeeds the first time.

What to do if your website is hacked

Work in this order. Each step protects the next one: evidence before cleaning, cleaning before passwords, passwords before the review. The commands below are for WordPress with WP-CLI; the ideas are the same on any platform.

1. Freeze the evidence and contain it

Before changing anything, copy the hacked state somewhere outside the web root. You will want it to find the way in and to compare later.

Shell
# Run in the WordPress folder (WP-CLI)
wp db export ~/hacked-$(date +%F).sql
tar -czf ~/hacked-files-$(date +%F).tar.gz .
wp maintenance-mode activate

Tell your host. Many have a malware team, and on shared hosting the infection may have come from, or spread to, a neighbouring account.

2. Update everything

Update the CMS core, every plugin, every theme. Delete plugins and themes you do not use, including inactive ones; their files are still reachable. Plugins closed on wordpress.org get no more fixes, so replace them (see abandoned WordPress plugins).

3. Find the injection and the backdoor

The visible spam is only half of it. Somewhere there is a backdoor, a file or database entry that lets the attacker back in or re-adds the spam. Start with core files, which WP-CLI can compare with the official checksums:

Shell
wp core verify-checksums
wp plugin verify-checksums --all

Then search the files, using the domains you wrote down:

Shell
# The spam domain anywhere in the site's files
grep -rl "spam-domain.example" wp-content/ wp-config.php index.php .htaccess

# Obfuscated PHP: legitimate plugins use these too, so review each hit
grep -rlE "eval\(|base64_decode|gzinflate|str_rot13" --include=*.php wp-content/

# PHP files do not belong in uploads
find wp-content/uploads -name "*.php"

# Must-use plugins run without appearing under Plugins
ls -la wp-content/mu-plugins/

Then the database, where spam links and scripts hide in posts, widgets and options:

Shell
wp db search "spam-domain.example"
wp db search "document.referrer"
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
wp cron event list --fields=hook,next_run_relative

Delete administrator accounts you do not recognise (reassign their content), and cron hooks that belong to no plugin you run. The WordPress recovery guide adds how to find the entry point in the access logs.

4. Reinstall from clean sources

Removing the visible spam is not enough; a backdoor elsewhere puts it back within hours. Replace code you did not write with fresh copies:

Shell
wp core download --force --skip-content
wp plugin list --field=name | xargs -n1 wp plugin install --force

Reinstall premium plugins and the theme from the vendor's download, and review your child theme's files by hand. A scanner plugin (Wordfence, Sucuri, MalCare and others) is a useful second opinion afterwards, not a replacement for these steps.

Tip

Restore a backup instead when you have one from before the hack and can tell when that was. Search the backup for the spam domain before you restore it. If the site is complex, the injection keeps returning, or you are not comfortable on the command line, a professional cleanup service is money well spent. Backups that actually restore covers what a usable backup needs.

5. Change every key

The attacker may have copied credentials. Change the passwords of every administrator, the hosting panel, SFTP/SSH and the database (then update DB_PASSWORD in wp-config.php). New salts log everyone out, including any stolen session:

Shell
wp config shuffle-salts

Rotate API keys stored on the site: payment gateways, SMTP, backups, CDN. If the checker found a readable .env, assume every secret in it has been copied.

6. Ask Google to review

When the site is clean, open Search Console → Security & Manual Actions → Security issues, tick that you fixed the issues and request a review. Describe what you found and removed. Google's Search Console Help says a review can take from a few days to a few weeks. Pages Google dropped come back as it recrawls them; the steps in why your page is not in Google help after that.

Platform notes

WordPress

WordPress is the most common target because it is the most common CMS. The usual ways in are an outdated or closed plugin, a stolen or guessed password, and a neighbouring account on shared hosting. The steps above are the short version; the full WordPress recovery guide covers containment, the access logs, reinstalling, verifying with a Googlebot comparison and monitoring for re-infection.

Shopify, Wix and other hosted platforms

The platform runs the servers, so file-level injections are rare. Spam usually arrives through a compromised staff account or an app: review Settings → Users and permissions, remove apps you do not recognise, and compare the theme's code with an older theme version in Online Store → Themes.

Static sites and custom code

The injection sits in the server config, the deploy pipeline or a compromised dependency. Redeploy from your repository to a clean server, compare the live files with the build, and check nginx.conf or .htaccess for rules matching Googlebot or HTTP_REFERER.

How to stop the next one

  • Update weekly, or turn on automatic updates for plugins you trust. The checker's CMS version finding flags an old core.
  • Give each person their own account with the lowest role that works, and two-factor login for administrators. The admin user and author archives covers the "admin" account.
  • Remove plugins you no longer use.
  • Put a WAF in front: your host's, Cloudflare's or a security plugin's.
  • Stop file edits from the dashboard, in wp-config.php above "That's all, stop editing!":
PHP
define('DISALLOW_FILE_EDIT', true);
  • Watch for file changes (most security plugins can alert you) and keep daily off-site backups with at least 30 days of history, so a clean copy exists when you notice late.

WordPress security basics without a plugin covers the rest of the hardening, from file permissions to XML-RPC. The change monitor, which emails you when a page's text changes, is a funded unlock: it switches on once donations cover it.

Verify

  • Re-run the hacked site checker: all three columns show the same words and links, and the four hack findings pass.
  • Test the URLs Google listed with spam, not only the home page.
  • URL Inspection's crawled HTML contains none of the spam domains.
  • Search Console's Security issues report shows no issues after the review.
  • A week later, re-run it; a returning injection means a backdoor survived.

Common mistakes

  • Cleaning the symptom, not the backdoor. Deleting the spam links from the footer works until the hidden file re-adds them tonight. Verify checksums and reinstall code (steps 3 and 4).
  • Restoring an infected backup. The attacker was often inside weeks before the spam appeared. Search the backup for the spam domain before restoring it.
  • Requesting a review too early. A failed review makes the next one slower. Wait until the checker, URL Inspection and a site: search are all clean.
  • Trusting "no differences" alone. The tool tests one URL; injections often target old posts or generated pages. Test the URLs Google shows, and read the hacked site learn page for the patterns.
  • Changing only the WordPress password. Hosting, SFTP, database and API keys are all in reach of the attacker. Change them all, and shuffle the salts.

Questions people ask

How do I know if my website is hacked?

Search Google for site:yourdomain.com and look for pages or titles you never published, especially pharma, casino or Japanese text. Other signs: the "This site may be hacked" label, visitors saying Google sent them to another site, a sudden drop in search traffic, or unknown owners in Search Console. Then compare what Googlebot and a visitor see with the hacked site checker, and check Search Console's Security issues report.

What should I do if my website is hacked?

Act in order: back up the hacked state for evidence, take the site into maintenance if it redirects visitors, update the CMS, plugins and themes, find and remove the injection and any backdoors, reinstall core and plugins from clean sources, change every password and key, then request a review in Search Console. Ask your host for help early; some scan and restore at no charge.

How do I fix a hacked website?

Replace rather than repair. Restore a backup from before the hack if you have one and have checked it, or reinstall the CMS, plugins and theme from their official sources and keep only your own content and uploads. Then remove unknown admin accounts and cron jobs, change every password and key, and update everything. Editing out the visible spam alone rarely works, because a backdoor re-adds it.

How do I remove malware from a website?

Find it first: compare core files with official checksums, search the files for obfuscated code such as eval(base64_decode(, look for PHP files in upload folders, and search the database for injected scripts. Then delete what you found and reinstall the code from clean copies, so nothing you missed survives. A server-side scanner from your host or a security plugin helps find it; it does not replace the reinstall.

Can I fix a hacked website myself?

Often, yes, if you can work with files and the database and have a clean backup or the original plugin and theme downloads. Follow the order in this guide: save evidence, update, remove the injection and the backdoor, reinstall code, change every password, then request a review. Pay a professional when the spam keeps returning, the site takes payments, or you are not comfortable on the command line.

How do I find where spam was injected in WordPress?

Look where attackers usually hide it: recently changed PHP files in wp-content, unknown plugins or files in wp-content/mu-plugins, new administrator accounts, and injected options or posts in the database. Compare core files with a clean copy using wp core verify-checksums from WP-CLI. Change every password and the security keys afterwards, because the way in is often a stolen login or an outdated plugin.

Can a website malware scanner find SEO spam?

Only some. Server-side malware scanners look at files on disk and in the database, which is where backdoors hide, but many miss spam that is served only to Googlebot or only to visitors from Google. An outside check that compares what Googlebot and visitors get catches that cloaked spam, but cannot see files. getReport's checker is the outside kind; for a full cleanup you need both.

Why does Google show spam for my site when I cannot see it?

Because the hack is cloaked. The injected code checks each request and serves spam only to Googlebot, or redirects only visitors who arrive from a Google result, while anyone typing your address gets the normal page. Logged-in owners are often skipped on purpose. Use URL Inspection in Search Console, or compare fetches as Googlebot and as a visitor, to see what Google sees.

What is SEO spam?

SEO spam is content an attacker injects into a hacked site to push their own pages in search results: hidden links to pharmacy, casino or loan sites, thousands of auto-generated pages, or redirects for visitors from Google. It borrows your domain's reputation. Because it is often cloaked from the owner, the first sign is usually strange titles in Google's results or a warning label, not anything visible on the site.

Everything in Hacked websites

Check your site before and after Check