Good to know: SecurynAI's free tier is a fully deterministic security plugin on its own — firewall, scanning, and hardening all work with no setup. Plain-English AI explanations require your own OpenAI or Anthropic API key (typically ~$0.10–$0.30/month); without one, you still get clear fallback explanations, just not full AI narratives.

What WordPress cron actually is

wp-cron.php is how WordPress runs scheduled tasks — publishing a scheduled post, checking for updates, sending a batch of emails, running a plugin's periodic cleanup job. It's not a real system-level cron job by default; it fires based on site visits. Plugins and themes are allowed to register their own scheduled tasks, and most of the time that's completely legitimate.

How one actually gets registered

A rogue cron job doesn't appear on its own — it's created the same way a legitimate plugin creates one: by code calling WordPress's own wp_schedule_event() function. The difference is where that call lives. Once an attacker has any way to run PHP on your site at all — a vulnerable plugin, an uploaded file, an injected snippet in a theme file — one line calling wp_schedule_event() is enough to plant a task that keeps running long after the original entry point is patched or removed. This is exactly why a rogue cron job is a symptom, not the root problem: something already had to be running arbitrary code on your site before it could schedule anything.

Why attackers use it

A scheduled task is an appealing way to keep access to a compromised site, because it runs automatically and repeatedly without needing an active login. A rogue cron job registered by an attacker might:

  • Re-download or re-create a backdoor file if it gets removed
  • Send spam email in batches on a schedule
  • Periodically "phone home" to report the site is still compromised
  • Re-apply a malicious change if you undo it manually

That last one is why cleanup sometimes seems to "not stick" — if the persistence mechanism itself isn't found and removed, whatever it recreates will just come back. Sucuri has documented this pattern directly: sites cleaned of malware kept getting reinfected because a scheduled task, not a file, was doing the reinfecting. The "Konami code" backdoor campaign took this further, running its reinfection task every single minute — which is the kind of frequency that should stand out immediately once you know to look for it.

Sucuri's research into this goes back further than one campaign — a multi-year thread they've called "the City of Cron" describes infections where cleanup felt like playing whack-a-mole for a genuine reason: the cron task didn't just re-add one file, it recreated deleted database options and silently re-added itself to the site's active plugin list on every run. Removing what's visible without finding the scheduled task driving the recreation just resets the clock until the next run.

How to tell a rogue task from a legitimate one

  1. List what's actually scheduled. If you have shell access, WP-CLI shows every registered cron event directly, including ones that don't come from anything currently visible in your plugin list:
    What you'd type
    wp cron event list
    A hook name like wp_update_plugins is normal core behavior; a hook name that's random-looking, or tied to a plugin you already deleted, is worth investigating.
  2. Look for tasks tied to nothing you recognize. A scheduled hook name that doesn't match any installed, active plugin is worth investigating — especially if a plugin it once belonged to has since been deleted but the task is still running.
  3. Check the frequency. Extremely frequent tasks (every minute, every few minutes) are more consistent with malicious "check-in" behavior than most legitimate plugin maintenance tasks.
  4. Correlate with other issues. A rogue cron job rarely shows up alone — it's usually one piece of a broader compromise that also includes a modified file or an unfamiliar admin account somewhere.

What the output actually looks like

A legitimate hook and a suspicious one often sit right next to each other in the same list. For example:

wp cron event list (illustrative)
hook                        next_run_gmt          recurrence
wp_version_check            2026-08-31 02:00:00    12 hours
wp_update_plugins           2026-08-31 02:00:00    12 hours
woocommerce_cleanup_carts   2026-08-31 03:00:00    1 day
sync_data_bridge_x92        2026-08-31 00:01:00    1 minute

The first three are unremarkable — core's own version/plugin update checks, and a recognizable WooCommerce housekeeping task. The fourth is the one to pull on: a hook name that reads like nothing a human named on purpose, running every single minute. That combination — meaningless name, aggressive frequency — is the exact pattern Sucuri's research and the Konami-code campaign both describe.

WP-Cron vs. a real system cron

Everything above assumes WordPress's own cron, which only fires when someone visits the site. Plenty of hosts disable that default and instead point a genuine server-level cron job at wp-cron.php on a fixed schedule (often exactly to make WP-Cron's timing more reliable on low-traffic sites). If that's your setup, checking wp cron event list is still correct — it shows what WordPress itself has scheduled — but it's worth also glancing at the server's actual crontab or your host's cron-manager panel. A persistence mechanism doesn't have to register through WordPress's hook system at all; a compromised site can just as easily get a raw system cron entry added directly, which wp cron event list will never show you because it isn't a WordPress event.

What to do if you find one

  • Don't just deactivate it and move on. Find and remove the actual malicious file or code the task is calling — removing only the schedule can leave the payload in place for something else to trigger it.
  • Check file integrity across the site, not just the plugin the task appears to belong to.
  • Change credentials for every admin account once you've confirmed a compromise.

Removing a cron job that won't go away cleanly

Once you've found and removed the actual malicious file, clear the schedule itself so nothing re-registers it:

What you'd type
wp cron event delete sync_data_bridge_x92

One real gotcha worth knowing: WordPress cron runs quietly during a normal page visit, and PHP errors from a broken or already-deleted callback usually just get swallowed or logged somewhere you're not watching. Run the same event through WP-CLI, though, and a missing handler throws a fatal error right in your terminal instead of hiding in a log — which is actually useful information, since it confirms the hook belongs to code that's no longer there.

If a cron entry still won't clear — WordPress stores every scheduled event as one serialized array in a single wp_options row named cron, and on rare occasions that row gets corrupted rather than just orphaned. If deleting the specific hook doesn't stick, renaming that one option row (e.g. to cron_old) forces WordPress to regenerate a clean cron array from scratch on the next page load — a more surgical fix than reaching for a full database restore.

Where this fits with a broader security setup

A standalone "suspicious cron job" scanner is only one narrow piece of what a real compromise looks like. Tools that watch file integrity, admin account activity, and login behavior are more likely to catch the actual entry point — the modified file or new admin account that let the attacker set the cron job up in the first place — even when the scheduled task itself isn't the thing being watched directly.

Check what's actually changed on your site.

Install free