¿Existe una vulnerabilidad conocida para wp-cron.php?

9

Estoy usando WordPress v.4.1 y todos los complementos y el tema están actualizados.

Veo en mis archivos de registro demasiados de estos ...

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"

donde xxx.xxx.xxx.xxx es la dirección IP del servidor donde está alojado el sitio web y " http://www.example.com " es mi sitio web.

¿Existe una vulnerabilidad conocida (exploit) que afecta a wp-cron.php?
¿Hay alguna manera de "proteger" el archivo?

¡Gracias!

kanenas
fuente

Respuestas:

4

En wp-includes/default-filters.phppodemos encontrar un registro de devolución de llamada:

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

Si vamos a la función wp_cron()ahora, vemos esto:

$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() envía la solicitud POST que está viendo en sus registros:

$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'] );

Aquí también puede ver de dónde proviene el número flotante: se pasa como un argumento para identificar el transitorio.

Nada de que preocuparse.

fuxia
fuente
-1

Si desea proteger el archivo, puede restringir el acceso al archivo a través de su httpd.conf (archivo de configuración global de Apache).

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

Reemplace la IP en el ejemplo con la IP de su servidor. Esto aún le dará acceso al archivo desde el servidor utilizando un comando como:

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

Y devolverá un 403 (acceso denegado a solicitudes de cualquier otra IP). Si usa una regla adicional como la siguiente, redirigirá las solicitudes externas desde 403 Forbiddenotra página (como la página de inicio) que realmente no es necesaria.

ErrorDocument 403 https://www.domain.ca

Aún mejor, se puede utilizar Require ip 127.0.0.1con el ejemplo anterior y utilice la solicitud de wget: wget -q -O - 127.0.0.1/wp-cron.php?doing_wp_cron. Eso usará el controlador de red de bucle invertido y su solicitud no se enviará a Internet pública ni se devolverá.

jonnyjandles
fuente
1
eso bloqueará las invocaciones del sistema operativo cron que generalmente se hacen usando wget
Mark Kaplun
¿Me puede indicar dónde se llama wget en el código fuente? La búsqueda rápida no me ayudó a encontrarla rápidamente. Encontré varias referencias para wget, pero solo en los complementos de WordFence y BulletProof.
jonnyjandles
Wordpress no usa cron del sistema operativo. Además, usando la regla anterior, pude wget wp-cron.php usando wget localhost / wp-cron.php y wget 127.0.0.1/wp-cron.php . Sin embargo, cuando intento acceder desde el exterior, hago lo siguiente en access_log "GET /wp-cron.php HTTP / 1.1" 302 (redirección). Porque yo también tengo un ErrorDocument 403 domain.com/index.php cuales rutas de todos los denegado el acceso a la página de inicio.
jonnyjandles
cron se solicita http desde el núcleo de wordpress. Todos los tutoriales disponibles en la red sugieren que use wget para activar WP cron desde el sistema operativo cron como un reemplazo para WP native crin trigger. Además, el filtrado por IP, que siempre es una estrategia perdedora, es aún peor en este caso, ya que cuando mueves tu sitio, cron dejará de funcionar y no sabrás por qué o esas líneas dejarán de tener efecto
Mark Kaplun,
Use 127.0.0.1 en lugar de la IP pública del servidor como mencioné en mi respuesta en ese momento.
jonnyjandles