Skip to content

Anyone can run your site's scheduled tasks through wp-cron.php

Warning Whole domain Security

General instructions. Open this article from your PageCheck report to see it filled in with your site's address and the rules for its web server.

What it is

WordPress runs its scheduled tasks — publishing scheduled posts, sending e-mails, backups, plugin updates — through the file wp-cron.php. Out of the box it starts that file itself while visitors browse the site, so the file has to answer requests from the internet.

What is wrong

The file answers requests from anyone, so anyone, bots included, can start the site's scheduled tasks as often as they like. Each request makes WordPress load in full, so repeated requests are a cheap way to load the server and slow the site down. Tasks started by visits are also unreliable: on a quiet site they run late.

How to fix

Do the steps in this order: blocking the file first would stop scheduled posts and e-mails.

1. Run the scheduled tasks from the server. Add a scheduled task (cron job) in your hosting control panel that runs every 5 minutes:

  • Plesk: Websites & Domains → Scheduled Tasks → Add Task, type "Run a PHP script", script httpdocs/wp-cron.php.
  • cPanel: Cron Jobs, command cd /home/USER/public_html && php wp-cron.php (with your own account name and folder).
  • A server with WP-CLI: wp cron event run --due-now --path=/path/to/site.

Run the file with PHP on the server, not by opening its address over the internet (wget or curl): step 3 blocks that. Managed WordPress hosts often have a server task already — ask them.

2. Stop WordPress starting it on page views. Add this line to wp-config.php, above the line /* That's all, stop editing! */:

wp-config.php

define( 'DISABLE_WP_CRON', true );

3. Block the file to the outside. Use the rule for your web server (your host can tell you which one it is):

Apache or LiteSpeed: in the .htaccess file in the site's main folder, above the "# BEGIN WordPress" line

<Files "wp-cron.php">
    Require all denied
</Files>

nginx: in the site's server block

location = /wp-cron.php {
    deny all;
}

On Cloudflare you can block it there instead: Security → WAF → Custom rules, a rule "URI Path equals /wp-cron.php" with the action Block.

4. Check it. Open https://example.com/wp-cron.php: it should now answer "Forbidden" (403). Schedule a test post a few minutes ahead and see that it is published on time, then run this check again.

Close wp-cron.php on my WordPress site to requests from the internet, without breaking scheduled tasks. https://example.com/wp-cron.php currently answers anyone.
The web server type is not known; check which one the site runs on.

Steps, in this order:
1. Set up a server-side scheduled task that runs WordPress cron every 5 minutes with PHP on the server (php wp-cron.php from the site's folder, or wp cron event run --due-now). Not wget/curl over HTTP: step 3 would block it.
2. Add define( 'DISABLE_WP_CRON', true ); to wp-config.php above "That's all, stop editing!".
3. Deny HTTP access to /wp-cron.php: on Apache/LiteSpeed a <Files "wp-cron.php"> Require all denied </Files> block in .htaccess above # BEGIN WordPress; on nginx location = /wp-cron.php { deny all; } in the server block.
4. Verify: /wp-cron.php answers 403, wp cron event list shows no overdue events after 10 minutes, and a post scheduled a few minutes ahead is published on time.
Tell me exactly which files you changed and what to check in the hosting control panel.

Resources:
- Hooking WP-Cron into the system task scheduler (WordPress.org): https://developer.wordpress.org/plugins/cron/hooking-wp-cron-into-the-system-task-scheduler/

Check your site to see whether it has this problem. Check a website