"Hacked: Code injection": tracing injected scripts in WordPress
Google's description: "A hacker has compromised your site and is injecting malicious code in your pages." Its examples are redirects to a malicious site and cryptocurrency mining that runs in the visitor's browser while the page is open. The code may sit directly in HTML, or in the files that generate it, which on WordPress means PHP files and the database.
This page is about finding that code. The broader cleanup order (credentials, reinstalling core and plugins, closing the hole) is on the Hacked: Malware page. Hydrogen SEO does not scan for or remove injected code; you will be working with files, the database and, often, your host.
Fetching infected pages without getting infected
Google advises against opening infected pages in your browser. Use URL Inspection to see the page as Google sees it, since attackers often show the malicious part only to Google or only to search visitors. From the command line, pretend to be a searcher by setting a referrer and user agent, and try different ones if nothing appears:
curl -sv -e 'https://www.google.com/' -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0' https://example.com/page.html -o page.html 2>&1 | grep -iE '^< (HTTP|location)'
grep -noE '<script[^>]*src="[^"]+"' page.html
grep -noE 'eval\(|atob\(|unescape\(|String\.fromCharCode|document\.write' page.html
A Location header to a foreign domain means a server-side redirect, often from .htaccess or PHP. A script tag loading from a domain you do not use, or long encoded strings passed to eval, means injected JavaScript.
The four shapes Google describes
Google lists the techniques it sees most:
| Technique | What it looks like | Where to look on WordPress |
|---|---|---|
| Header redirect | 301 with Location: to an unknown site | .htaccess, server config, PHP header() calls in theme or mu-plugins |
| JavaScript redirect | if (document.referrer.match(/google\.com/)) then window.location | Post content, widgets, theme header/footer, options rows |
| Script loaded from another site | <script src="https://unknown.example/js/x55.js"> | Options such as custom header scripts, theme files, fake plugin |
| Obfuscated code | eval(base64_decode("...")) | PHP files anywhere in wp-content, wp-config.php, sometimes core files |
In-browser cryptocurrency miners usually fall in the third row: a script tag pulling a miner library from an outside host. A visitor's symptom is a page that makes the laptop fan spin up or the phone warm; in DevTools, the Performance panel shows one script using the CPU constantly while the page sits idle.
The report's example list is only a sample, and Google notes it sometimes cannot generate examples at all. That does not mean no pages are affected. Because WordPress builds every page from the same theme and options, an injection found on one URL is usually present on all of them.
Searching the database and files
WordPress sites store a lot of front-end output in the database, which is why a clean reinstall of files alone often leaves the injection in place.
# Database: script tags and encoded payloads in options and posts
wp db search '<script' wp_options --one_line
wp db search 'eval(' --all-tables --one_line
wp db search 'fromCharCode' --all-tables --one_line
# Files: the terms Google suggests, plus common helpers
grep -rlE 'base64_decode|eval\(|gzinflate|str_rot13|unescape' wp-content/ wp-config.php
find . -name '*.php' -newer wp-config.php -mtime -30
Expect false positives: some legitimate plugins use base64_decode. Compare suspicious files with a fresh download of the same plugin or theme version. Anything in wp-content/uploads ending in .php is almost never legitimate. When you remove injected content from options, edit the specific value rather than deleting the whole row, which may hold your real settings.
Cleaning and asking for the review
Google gives two routes: replace affected files with the last good backup, or remove the malicious code yourself. Backups are only good if they predate the infection and you then patch the way in. Either way, finish with the wider steps on the malware page, because injected code nearly always comes with a backdoor that puts it back.
When fetches with search referrers and several user agents come back clean on all example URLs, select Request Review in the Security issues report. Name the injection points you found (for instance, "a script tag in the wp_options row for the theme's header scripts, and an eval loader in mu-plugins/cache.php") and how the attacker got in. Google puts security reviews at a few days to a few weeks. If the code comes back before the review, the request fails and the next one may take longer, so monitor with the same curl commands daily until you hear back.
Common questions
Why does the injected code not appear when I view my own site?
Attackers often target only visitors arriving from search engines, specific user agents, or crawlers, and skip logged-in administrators. Fetch pages with curl using a Google referrer, or use URL Inspection.
Is every file containing base64_decode malicious?
No. Some legitimate plugins use it. Compare the file with a clean copy of the same plugin version, and be suspicious of long encoded strings passed straight to eval.
Will reinstalling WordPress remove injected code?
It replaces core files, but injected scripts often live in the database, the theme, uploads or must-use plugins. Search those too.