Есть ли известная уязвимость для wp-cron.php?

9

Я использую WordPress v.4.1 и все плагины и тема обновлены.

Я вижу в моих файлах журнала слишком много из них ...

xxx.xxx.xxx.xxx - - [02/Jan/2015:13:30:27 +0200] "POST /wp-cron.php?doing_wp_cron=1420198227.5184459686279296875000 HTTP/1.0" 200 - "-" "WordPress/217; http://www.example.com"

где xxx.xxx.xxx.xxx - это IP-адрес сервера, на котором размещен веб-сайт, а « http://www.example.com » - мой веб-сайт.

Есть ли известная уязвимость (эксплойт), затрагивающая wp-cron.php?
Есть ли способ «защитить» файл?

Спасибо!

kanenas
источник

Ответы:

4

В wp-includes/default-filters.phpможно найти регистрацию обратного вызова:

// WP Cron
if ( !defined( 'DOING_CRON' ) )
    add_action( 'init', 'wp_cron' );

Если мы перейдем к функции wp_cron()сейчас, мы увидим это:

$schedules = wp_get_schedules();
foreach ( $crons as $timestamp => $cronhooks ) {
    if ( $timestamp > $gmt_time ) break;
    foreach ( (array) $cronhooks as $hook => $args ) {
        if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
            continue;
        spawn_cron( $gmt_time );
        break 2;
    }
}

spawn_cron() отправляет запрос POST, который вы видите в своих журналах:

$doing_wp_cron = sprintf( '%.22F', $gmt_time );
set_transient( 'doing_cron', $doing_wp_cron );

/**
 * Filter the cron request arguments.
 *
 * @since 3.5.0
 *
 * @param array $cron_request_array {
 *     An array of cron request URL arguments.
 *
 *     @type string $url  The cron request URL.
 *     @type int    $key  The 22 digit GMT microtime.
 *     @type array  $args {
 *         An array of cron request arguments.
 *
 *         @type int  $timeout   The request timeout in seconds. Default .01 seconds.
 *         @type bool $blocking  Whether to set blocking for the request. Default false.
 *         @type bool $sslverify Whether SSL should be verified for the request. Default false.
 *     }
 * }
 */
$cron_request = apply_filters( 'cron_request', array(
    'url'  => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ),
    'key'  => $doing_wp_cron,
    'args' => array(
        'timeout'   => 0.01,
        'blocking'  => false,
        /** This filter is documented in wp-includes/class-http.php */
        'sslverify' => apply_filters( 'https_local_ssl_verify', false )
    )
) );

wp_remote_post( $cron_request['url'], $cron_request['args'] );

Здесь вы также можете увидеть, откуда приходит число с плавающей точкой: оно передается в качестве аргумента для определения переходного процесса.

Не о чем беспокоиться.

Фуксия
источник
-1

Если вы хотите защитить файл, вы можете ограничить доступ к файлу через ваш httpd.conf (глобальный конфигурационный файл Apache).

# Wordpress wp-cron.php file
<Files "wp-cron.php">
  Require ip 1.2.3.4
</Files>

Замените IP в этом примере на IP вашего сервера. Это все равно даст вам доступ к файлу с сервера с помощью команды вроде:

wget -q -O - domain.com/wp-cron.php?doing_wp_cron

И он вернет 403 (доступ запрещен для запросов с любого другого IP). Если вы используете дополнительное правило, например, приведенное ниже, вы будете перенаправлять внешние запросы с 403 Forbiddenдругой страницы (например, домашней страницы), которая на самом деле не нужна.

ErrorDocument 403 https://www.domain.ca

Даже лучше, вы можете использовать Require ip 127.0.0.1вышеупомянутый пример и использовать Wget запрос: wget -q -O - 127.0.0.1/wp-cron.php?doing_wp_cron. При этом будет использоваться сетевой контроллер обратной связи, и ваш запрос не будет перенаправлен в общедоступный Интернет и обратно.

jonnyjandles
источник
1
это будет блокировать вызовы из cron ОС, которые обычно выполняются с помощью wget
Марк Каплун
Можете ли вы указать мне, где в исходном коде вызывается wget? Быстрый поиск не помог мне быстро его найти. Я нашел несколько ссылок на wget, но только в плагинах WordFence и BulletProof.
jonnyjandles
Wordpress не использует ОС crons. Кроме того, используя указанное выше правило, я смог wget wp-cron.php, используя как wget localhost / wp-cron.php, так и wget 127.0.0.1/wp-cron.php . Тем не менее, при попытке доступа извне я следующее в access_log "GET /wp-cron.php HTTP / 1.1" 302 (перенаправление). Потому что у меня тоже есть ErrorDocument 403 domain.com/index.php который направляет весь доступ запрещен к домашней странице.
jonnyjandles
cron запрашивается http из ядра WordPress. Все учебные пособия, доступные в сети, предполагают, что вы используете wget для запуска WP cron из OS Cron в качестве замены для запуска собственного крипта WP. Кроме того, фильтрация по IP, которая всегда приводит к тому, что стратегия проигрыша еще хуже в этом случае, поскольку, когда вы перемещаете свой сайт, либо cron перестает работать, и вы не будете знать, почему или эти строки перестанут
Марк Каплун
Используйте 127.0.0.1 вместо публичного IP-адреса сервера, как я уже упоминал в своем ответе.
Jonnyjandles