Dangers of Drupal Cron

30 November -0001

Cron is the Unix scheduling daemon used to run tasks at regular intervals. Cron is included with Unix, Linux, and Mac OS and is frequently present on LAMP installations with Drupal. Drupal is a complex web application and content management system (CMS) and it relies on certain administrative and maintenance tasks to be performed at regular intervals. Every Drupal installation includes a PHP script called 'cron.php' that can be called directly through a browser in the same way as the rest of the Drupal installation. This script, when called, triggers several background tasks, but does not display any information directly. While it is conceivable to simply visit the cron.php page on a regular basis to perform Drupal administrative tasks, it is much easier to schedule a call to this page.

In a typical Linux environment the wget command would be used to make this URL request. By scheduling the wget command using cron the cron.php script can be run at a set interval. This aids in system maintenance and eliminates the need for manual visits to the cron.php page.

The Drupal default installation and configuration presents several security challenges and potential vulnerabilities with scheduling cron. Drupal includes two shell scripts, cron-curl.sh and cron-lynx.sh, in the scripts directory of default installations. The scripts are intended to be included in a crontab in order to facilitate the regular calling of cron.php. By default these scripts are set as readable and writable by their owner.

In the 'Example scripts' portion of the Drupal.org site (http://drupal.org/cron) there are instructions for scheduling Drupal's cron.php using the scripts provided with the Drupal installation.

There are several problems with the typical setup of Drupal cron jobs. The first is that when a cron job is scheduled it is run with the privileges of the user who owns the crontab. In the case of /etc/crontab this user is usually root. What this means is that the content of the shell scripts cron-curl.sh or cron-lynx.sh are run as the user who schedules the cron tab.

The second problem with the default setup is that the cron scripts cron-curl.sh and cron-lynx.sh are writable, meaning they can be modified by their owner.

In a typical situation a user may change the ownership of all files and directories in their Drupal installation to the web user, such as 'apache'. This eliminates headaches with the web server accessing files and being able to write to directories like files/ on the Drupal installation.

The problem with this setup is that if the web server process is ever compromised (for instance by a malicious user who gets access to write PHP using a vulnerable or misconfigured Drupal module) then that user could write additional commands in the cron-curl.sh or cron-lynx.sh shell scripts. These commands would then be run with the privileges of the user who scheduled the cron job. In the case of a regular system user this could lead to system account compromise, so the malicious Drupal user could take control of the web server account, then take control of a user account. It is likely that any user who scheduled the crontab has interactive shell access to the server - allowing the attacker to move from a web attack to a local account compromise.

If the cron job happened to be scheduled to run as root, for instance in a case where an administrator simply added the cron-curl.sh script to /etc/crontab, the compromise of the webserver could mean a total system compromise. In a worst case vulnerability scenario the cron scripts are owned and writable by the web server (apache) but they are executed as root via crontab. This leads to a situation where control of the web server implicitly means control of the root account.

Note that an attacker might not necessarily have to compromise Drupal itself. Any vulnerability in another web application that let the attacker gain write access to the cron-curl.sh or cron-curl.sh would allow them to issue arbitrary commands as the user who scheduled the cron job that called those scripts.

Mitigating Strategies

It is best to not use the example scripts provided with Drupal installations. The fact that these scripts exist within a web accessible directory as part of the Drupal installation makes them dangerous. If you do wish to use these scripts, remove the write privileges to them with the command:

chmod u-w scripts/*

If you do this, however, you must be sure the web server account does not own the scripts or they could easily be changed back to writable. A better idea is to simply copy the contents of the shell scripts and manually add them to a cron job and deleting the scripts directory altogether. Be sure not to run the cron job that calls cron.php as root! Use an unprivileged user account instead.

It is important to be aware that these scripts exist within your Drupal installation so that you take steps to appropriately protect them. Review your cron strategy to ensure that it is safe and doesn't open your server to attack. Make sure that whomever is running cron jobs has system privileges only to accomplish the tasks necessary for the cron jobs and no more. Limiting privilege will decrease the window of exposure if the cron scripts are altered or compromised.