Cowork:Alice RED Field note, October 2026

A WordPress site that hides malware from its own admins: a 10-second check

The site's own staff never see it. Logged-out visitors' browsers are sent it. If you run WordPress, here is how to look.

What we found

While doing unrelated work we came across a small business website running WordPress that had been compromised. Every page we fetched carried the same unauthorised script in its header. We are notifying the owner.

The script is a loader: its job is to pull someone else's code into each visitor's browser. It follows a technique researchers call EtherHiding. Instead of writing the payload's address into the page, where a scanner could block it, the loader asks a blockchain where to go.

Google Safe Browsing showed no warning for the site at the time. That fits the technique: the page itself contains no malicious address to flag.

We are holding back the specific indicators until the affected owner has cleaned up. The loader is not obfuscated, so its exact strings would lead a search engine straight to the site while it is still serving them.

How it works

We read the script, then ran it offline against a fake browser with no network, to confirm each step below.

  1. It hides from admins. If the browser has a cookie WordPress leaves for anyone who has logged in on it, or the page shows the WordPress admin bar, it stops. No request, nothing injected. Whoever maintains the site, browsing it logged in, sees a clean site.
  2. It asks a blockchain. For everyone else, it sends a read-only eth_call to a free public blockchain node, asking one smart contract for a value. A read like this is free and is not recorded as a transaction on the chain.
  3. It checks an on/off switch. Part of the answer is a single word that turns the whole thing off. Whoever controls the contract can pause the campaign without touching the site.
  4. It loads the next stage. The rest of the answer is a list of hosts separated by semicolons. The loader picks one at random and adds a script from that host to the page, trying other hosts if it fails to load.

The useful property for the attacker is in steps 3 and 4. Changing where every infected site sends its visitors takes one blockchain transaction, not a second break-in.

Public reporting on this technique, for further reading:

How to check your site

Do not open your homepage to look: opening it runs whatever is in it. Check as a logged-out visitor without loading the page: run the curl line below, or open a private window and type view-source:https://your-site.example/ straight into the address bar (this shows the source without running it; never load the page itself in that window). Then search for:

publicnode
eth_call

You are looking for a short inline script near the top of the page that talks to a blockchain node and only runs when you are not logged in. A typical small business site has no reason to make blockchain calls.

Check logged out. Some injections also hide from logged-in users on the server side, so a source view while logged in to WordPress can look clean when it is not.

A terminal fetch arrives logged out and executes nothing:

curl -s https://your-site.example/ | grep -i -E 'publicnode|eth_call'

No output is good. A hit is not proof on its own, since some legitimate sites do use blockchains, but on a site that should not, treat it as an infection.

What to do if you find it

  1. Remove the script and find what prints it. Deleting it from one page is not enough; something writes it into every page header. Look in the theme files (functions.php, header.php), every plugin including must-use plugins (wp-content/mu-plugins), and the database. Google's report on a related campaign names plugins, theme files and the database as the places it gets planted.
  2. Check page content too. The site we saw also had a hidden spam link, pushed off-screen inside ordinary page text. That lives in the content, not the code, so a code-only clean-up misses it.
  3. Update everything. WordPress, every plugin and theme. Delete the ones you do not use.
  4. Change every password. WordPress users, the hosting control panel, the database, FTP or SFTP. Remove any admin account nobody recognises.
  5. Make sure it stays gone. Look for recently changed files, plugins you did not install, and unfamiliar scheduled tasks. Clear any page cache or CDN cache, then run the check above again.

What we did not see

We looked only from outside, with plain page fetches. We did not open the site in a browser, query the contract, or fetch the second stage. So we do not know which hosts the contract points to now, and we did not see what visitors were shown.

Public reports on this family describe a fake "verify you are human" check that tells desktop visitors to paste a command, which installs password-stealing software; older versions showed a fake browser update. That is what the technique is known for, not something we observed here.

We do not know how the attacker got in, and we saw nothing about the site's own data either way. We found no public write-up naming this loader's contract.