Il file wp-cron.php di WordPress è vulnerabile ad attacchi esterni e come proteggerlo?

29 gen 2015, 21:33:02
Visualizzazioni: 43.2K
Voti: 13

Sto utilizzando WordPress v.4.1 e tutti i plugin e il tema sono aggiornati.

Nei miei file di log vedo molte di queste righe...

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"

dove xxx.xxx.xxx.xxx è l'indirizzo IP del server che ospita il sito web e "http://www.example.com" è il mio sito web.

Esiste una vulnerabilità nota (exploit) che interessa wp-cron.php?
C'è un modo per "proteggere" il file?

Grazie!

0
Tutte le risposte alla domanda 2
0

Nel file wp-includes/default-filters.php possiamo trovare la registrazione di un callback:

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

Se ora andiamo alla funzione wp_cron(), vediamo questo:

$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() invia la richiesta POST che stai vedendo nei tuoi log:

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

/**
 * Filtra gli argomenti della richiesta cron.
 *
 * @since 3.5.0
 *
 * @param array $cron_request_array {
 *     Un array di argomenti URL per la richiesta cron.
 *
 *     @type string $url  L'URL della richiesta cron.
 *     @type int    $key  Il microtime GMT a 22 cifre.
 *     @type array  $args {
 *         Un array di argomenti per la richiesta cron.
 *
 *         @type int  $timeout   Il timeout della richiesta in secondi. Default .01 secondi.
 *         @type bool $blocking  Se impostare il blocking per la richiesta. Default false.
 *         @type bool $sslverify Se verificare SSL per la richiesta. 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,
        /** Questo filtro è documentato in wp-includes/class-http.php */
        'sslverify' => apply_filters( 'https_local_ssl_verify', false )
    )
) );

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

Qui puoi anche vedere da dove proviene il numero float: viene passato come argomento per identificare il transient.

Niente di cui preoccuparsi.

29 gen 2015 22:24:18
6

Se vuoi proteggere il file puoi limitare l'accesso al file tramite il tuo file httpd.conf (file di configurazione globale di Apache).

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

Sostituisci l'IP nell'esempio con l'IP del tuo server. Questo ti consentirà comunque di accedere al file dal server utilizzando un comando come:

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

E restituirà un 403 (accesso negato alle richieste da qualsiasi altro IP). Se usi una regola aggiuntiva come quella qui sotto, reindirizzerai le richieste esterne da 403 Forbidden a un'altra pagina (come la homepage), cosa che non è strettamente necessaria.

ErrorDocument 403 https://www.domain.ca

Ancora meglio, puoi usare Require ip 127.0.0.1 con l'esempio sopra e usare la richiesta wget: wget -q -O - 127.0.0.1/wp-cron.php?doing_wp_cron. Questo utilizzerà il controller di rete loopback e la tua richiesta non verrà inoltrata nella rete internet pubblica e ritorno.

6 giu 2019 17:56:50
Commenti

che bloccherà le invocazioni dal cron del sistema operativo che di solito vengono eseguite utilizzando wget

Mark Kaplun Mark Kaplun
6 giu 2019 19:17:03

Puoi indicarmi dove viene chiamato wget nel codice sorgente? Una ricerca rapida non mi ha aiutato a trovarlo velocemente. Ho trovato diversi riferimenti a wget, ma solo nei plugin WordFence e BulletProof.

I'm Root James I'm Root James
6 giu 2019 21:36:07

WordPress non utilizza cron del sistema operativo. Inoltre, usando la regola sopra, sono riuscito a eseguire wget wp-cron.php sia con wget http://localhost/wp-cron.php che con wget http://127.0.0.1/wp-cron.php. Tuttavia, quando ho tentato di accedere dall'esterno ho ottenuto quanto segue nell'access_log "GET /wp-cron.php HTTP/1.1" 302 (reindirizzamento). Questo perché ho anche un ErrorDocument 403 https://www.domain.com/index.php che indirizza tutti gli accessi negati alla homepage.

I'm Root James I'm Root James
6 giu 2019 21:45:16

cron viene richiesto via HTTP dal core di WordPress. Tutti i tutorial disponibili online suggeriscono di usare wget per attivare WP cron dal cron del sistema operativo come sostituto del trigger nativo di WP cron. Inoltre filtrare per IP, che è sempre una strategia perdente, è ancora peggio in questo caso perché quando sposti il sito, o il cron smetterà di funzionare e non saprai perché, o quelle righe smetteranno di avere alcun effetto

Mark Kaplun Mark Kaplun
7 giu 2019 19:20:41

Usa 127.0.0.1 invece dell'IP pubblico del server come ho menzionato nella mia risposta allora.

I'm Root James I'm Root James
7 giu 2019 22:13:05

WordPress non usa mai wget per WP-Cron e se scegli di configurare job cron a livello di sistema operativo, probabilmente non dovresti usare neanche wget. Questa risposta è intelligente, ma non va abbastanza lontano... potresti limitare l'accesso a wp-cron.php ma poi usare WP-CLI o /usr/bin/php per chiamarlo localmente.

Jesse Nickles Jesse Nickles
15 mar 2023 12:41:47
Mostra i restanti 1 commenti