Injected JavaScript in Your Site Header and Footer

By · Updated · 4 min read

You viewed your page source, or a scanner did it for you, and there is a script in there that you did not put there. It sits on every page, usually near the top or just before the closing body tag, and it either points at a domain you do not recognize or contains a wall of unreadable characters. The question is not really what the script does — it is what keeps putting it there.

Why the header and footer

WordPress gives themes and plugins two hooks that output code into every single page: one in the head and one just before the body closes. They exist for good reasons — analytics, fonts, chat widgets and consent banners all use them — and that legitimacy is exactly what makes them attractive. Code placed there runs on every page view, for every visitor, without touching individual posts.

So an attacker who can write to your theme, your database, or a plugin's settings gets site-wide JavaScript execution from a single change. It is the cheapest possible way to monetize a compromised site, and it is why this is one of the most common things I find.

Telling malicious from legitimate

Plenty of legitimate scripts look alarming if you are not used to reading them, so start by accounting for what should be there. Analytics and tag managers, advertising networks, chat widgets, consent tools and A/B testing platforms all inject minified code from third-party domains. Minified is not the same as obfuscated.

The distinctions that actually matter: a legitimate script usually comes from a domain you can recognize and verify, and you can trace it to a plugin setting or a line you added. A malicious one typically points at a domain with no relationship to any service you use, or contains no readable strings at all — just arrays of encoded values reassembled at runtime. The strongest signal is provenance. If nobody can explain how a script got onto the site, that is the finding, regardless of how it looks.

The four places it comes from

First, theme files — functions.php, header.php and footer.php, either as a direct script echo or as a function hooked into the head or footer actions. Second, the database, usually a wp_options row belonging to a plugin that legitimately injects custom code, which is the pattern behind campaigns like Sign1.

Third, a malicious or compromised plugin, including fake ones installed specifically to carry the payload and must-use plugins that never appear on the normal plugins screen. Fourth, and less often, injection at the server level through an .htaccess directive or a PHP configuration that prepends a file to every request. Checking all four is the difference between a fix and a temporary reprieve — my guides on hacked functions.php files, database malware and mu-plugins backdoors cover the first three.

Tracing it to its source

Work from the output backwards. Note exactly where the script appears in the rendered HTML and what surrounds it — code emitted by a theme template sits in a predictable position relative to other head elements, while code from a plugin hook lands in an order that reflects its priority. That position narrows the search considerably.

Then search the codebase for a distinctive fragment of the script itself: part of the domain, a variable name, an unusual string. If a file contains it, you have your source. If nothing in the files matches, the payload is in the database, and searching a database export for the same fragment will find the row. This is also where a staging copy earns its keep, because you can disable plugins one at a time there without anyone noticing.

Removing it and keeping it gone

Remove the injection at its source rather than filtering the output. Then look for what let it happen, because a script in your header means someone had write access to your files or your database, and that access is the actual problem. Check for backdoors, unrecognized administrator accounts, scheduled tasks and modified core files before you call it finished.

Rotate passwords and salts, update everything, and remove plugins you do not need — particularly any that exist to inject arbitrary code, since they are both a common vector and a convenient hiding place. Then verify from outside: fetch your pages without a login cookie and read the source, because many injections deliberately skip logged-in users.

Cleaning up the fallout

Injected JavaScript is the most common trigger for browser and antivirus warnings, so expect some cleanup beyond the site itself. If Chrome or Firefox is showing a warning, work through deceptive site warnings. If an antivirus vendor is blocking you, the blacklist removal links page collects the delisting forms.

Give it a couple of weeks of checking before you relax. If the script comes back, something survived the cleanup, and at that point the useful question is no longer what the script is but where the persistence lives — which is exactly the work my malware removal service does.

Common questions

How can I tell if a script is malicious or just minified?

Minified code is compressed but still structurally readable — you can see real function names, recognizable strings and a domain you can look up. Obfuscated malware hides its content on purpose: long encoded blobs, character-code arrays reassembled at runtime, no readable strings at all. The decisive test is not appearance though, it is provenance. If you cannot trace it to something you installed, treat it as hostile.

I removed the script from functions.php and it reappeared. Why?

Because something else is writing it. Usually that is a backdoor file that runs on every request and rewrites the theme, or a scheduled task doing the same on a timer. Removing the output without removing the writer just resets it. Look for recently modified PHP files and check your scheduled events.

Could this be coming from my hosting rather than my site?

Occasionally, yes. A compromise at the account level can prepend code to every PHP request through server configuration, and on shared hosting a neighbouring site under the same account can reach across. If you have thoroughly cleaned files and database and the injection still returns, that is the point to involve your host.

Does injected JavaScript hurt my rankings?

Indirectly and sometimes severely. The script itself is not a ranking factor, but a browser warning or a search-engine security flag on your listing devastates click-through, and if the injected code serves different content to crawlers you can pick up a manual action. The damage is usually reversible once the site is clean and reviewed.

Why do I see the script in the source but nothing happens when I visit?

Most of these injections are conditional. They skip logged-in users, skip repeat visitors via a cookie, or only fire for traffic arriving from search engines or on mobile devices. Seeing the code and not seeing the behaviour is normal, and it is not evidence that the script is harmless.