Security and crisis response
A 130-site WordPress portfolio looked clean. Google Ads knew something was wrong.
Google Ads saw what every scanner missed.
The sites looked clean, loaded normally, and returned clear scan results while paid ad traffic was being redirected.
Portfolio facts
- Client
- A 130-site WordPress portfolio
- Hosting
- Flywheel
- Timeline
- 15 days to full remediation
- Ongoing
- Monthly security review + weekly audit for high-profile sites
Sites clean
130
Every property in the portfolio was remediated and hardened.
Full remediation
15 days
File system remediation, database cleanup, credential rotation, and hardening.
Reinfections after three months
No
Google Ads accounts were reinstated after the malware was removed and evidence was submitted.
Summary
A clean-looking portfolio was silently redirecting paid traffic.
An agency owner who had just taken over a 130-site WordPress portfolio found their Google Ads accounts getting suspended repeatedly, with no obvious cause.
The job was not only technical cleanup. It was helping the agency regain control of a crisis they had inherited, with clear evidence they could use in Google Ads review and client-retention conversations.
Every site looked clean. Every scanner returned clear results. The infection had been running undetected across all 130 properties, silently redirecting paid ad traffic to rogue domains while evading every automated check.
In 15 days, the full portfolio was cleaned, hardened, and documented for Google Ads review. Three months later, all 130 sites remain stable, with no reinfections and no recurring ad suspensions.
Interactive incident model
See why the portfolio looked clean until paid traffic exposed it.
Server response
Blank file
Security scanners and automated crawlers received no executable redirect code.
Remediation progress
0 / 130
Timeline scrubber for the 15-day remediation window. It is a progress model, not a day-by-day production log.
Suspension cycle
Every day or two
The ad account does not get reinstated while malware is still present. The loop happens when only the visible flagged URL is treated, while the underlying infection keeps pulling fresh destinations and rotating delivery domains.
Evidence map
Hidden plugin, unauthenticated REST writes, wp-cron.php reinstaller, AES-256 payloads in /patterns/, and Google Ads-only JavaScript all pointed to the same compromise pattern.
4 layers
The situation
A trust problem, a paid-media problem, and a security problem at once.
A client brought us in after taking over a 130-site WordPress portfolio from a previous agency. Every site in the portfolio was running Google Ads. Within weeks of the handover, ad accounts began getting flagged and suspended for policy violations, one after another.
The sites loaded perfectly. Traffic patterns looked normal. There were no error messages, no visitor complaints, no server alerts. Yet every single property was compromised.
We worked as the agency's technical escalation layer: identifying the compromise, cleaning the portfolio, hardening the sites, and documenting the work so the agency could protect client trust while the recovery was underway.
Where the infection came from
The delivery infrastructure pointed to a wider compromise.
The evidence pointed to a compromised WordPress component used across the portfolio. It may have been a shared plugin, integration, or management tool. Because the same component was connected to all 130 sites, the exposure spread portfolio-wide.
Several of the sites had Wordfence installed and active throughout. It did not detect the infection or prevent re-infection.
The rotating domains hosting the malicious JavaScript files did not belong to the attacker. They were other compromised WordPress sites belonging to unrelated organisations that had no idea their servers were being used.
One delivery domain we identified resolved to the same server as a well-known international non-profit. The attacker had added their domain as a virtual host, planted the file, used it for a couple of days, then moved on. By the time any investigation caught up to a particular domain, the file was already gone.
Why nobody caught it
The malware was designed to look clean to the tools checking it.
Hidden plugin
A PHP plugin removed itself from the admin plugins screen, so standard dashboard audits looked clean.
Ad-click-only redirects
The delivery server served the real JavaScript only to browsers with active Google Ads session signals.
Hidden admin access
A specific GET parameter could log the attacker in as the site's first administrator.
Built-in reinfection
A reinstaller in wp-cron.php could recreate the plugin under a different directory name.
Google flags a URL and suspends the account. If only the flagged URL is addressed while the underlying infection remains, the attacker rotates delivery infrastructure, paid traffic is exposed again, and a new suspension follows.
The cycle kept running because the destination URL was never stored on the site. It was pulled fresh from the attacker's server on each page load, and the delivery domain rotated every day or two.
What we did
The same complete sequence, repeated site by site.
130 sites over 15 days
File system remediation
WordPress core files were reinstalled from verified checksums. Non-core directories were inspected manually and unauthorised PHP files were removed.
Database cleanup
Injected JavaScript strings were removed from wp_posts and wp_options without corrupting legitimate data.
Credential rotation
Active sessions were terminated, unauthorised admin accounts were removed, and credentials were rotated across every property.
Hardening
Login protections, file permission changes, attack surface reduction, and session invalidation were applied consistently.
The outcome
Clean sites, reinstated ads, and a review rhythm that keeps watching.
Three months on, all 130 sites remain clean. No re-infections, no redirects, no rogue admin accounts.
We provided the technical remediation evidence the agency needed to move through the Google Ads reinstatement process and explain the recovery with confidence. Once the malware was removed, the domains were verified clean, and the documentation was submitted, the accounts came back without the recurring suspensions that had defined the previous weeks.
There is now an ongoing engagement covering the full portfolio. High-profile sites get a weekly manual audit: file integrity checks, security log review, user account monitoring, and backup validation, with a written report after each session. The wider portfolio gets a monthly review cycle.
What this means for agency-managed portfolios
The conditions that allowed this infection are common.
There is no visible signal
The WordPress admin may look clean. The site may load normally. Scanners may report no issue. Paid traffic can still be compromised. Infections like this often surface through ad suspensions, not security alerts.
Any shared plugin can become a single point of failure
A shared plugin, integration, or centralised tool can spread exposure across every connected site if it is compromised. A trusted component is not the same thing as verified control.
Cleanup without hardening creates a loop
Removing malware is not the same as closing the entry point. In this case, a cleaned site without the added hardening layer was re-infected within 24 hours.
Automated tools are not enough
Finding this infection required direct file system review, database inspection, and behavioural testing. Several sites had Wordfence installed and active throughout, and it detected nothing.
Managing a WordPress portfolio with paid traffic behind it?
Shardul + Team helps agencies uncover hidden malware, recover compromised sites, and harden portfolios before silent infections turn into suspended ads, emergency calls, and client-retention problems.
Available for emergency escalations, discreet agency support, and white-label technical architecture.