Este wp-cron.php vulnerabil la atacuri externe și cum îl putem proteja?
Folosesc WordPress v.4.1 și toate plugin-urile și tema sunt actualizate la zi.
Văd în fișierele mele de log prea multe dintre acestea...
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"
unde xxx.xxx.xxx.xxx este adresa IP a serverului pe care este găzduit site-ul web și "http://www.example.com" este website-ul meu.
Există o vulnerabilitate cunoscută (exploit) care afectează wp-cron.php?
Există vreo modalitate de a "proteja" fișierul?
Mulțumesc!

În wp-includes/default-filters.php
putem găsi înregistrarea unui callback:
// WP Cron
if ( !defined( 'DOING_CRON' ) )
add_action( 'init', 'wp_cron' );
Dacă mergem acum la funcția wp_cron()
, vedem următoarele:
$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()
trimite cererea POST pe care o vedeți în jurnalele voastre:
$doing_wp_cron = sprintf( '%.22F', $gmt_time );
set_transient( 'doing_cron', $doing_wp_cron );
/**
* Filtrează argumentele cererii cron.
*
* @since 3.5.0
*
* @param array $cron_request_array {
* Un array cu argumentele URL-ului pentru cererea cron.
*
* @type string $url URL-ul cererii cron.
* @type int $key Timpul GMT în microsecunde (22 de cifre).
* @type array $args {
* Un array cu argumentele cererii cron.
*
* @type int $timeout Timeout-ul cererii în secunde. Implicit .01 secunde.
* @type bool $blocking Dacă cererea trebuie să fie blocantă. Implicit false.
* @type bool $sslverify Dacă SSL trebuie verificat pentru cerere. Implicit 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,
/** Acest filtru este documentat în wp-includes/class-http.php */
'sslverify' => apply_filters( 'https_local_ssl_verify', false )
)
) );
wp_remote_post( $cron_request['url'], $cron_request['args'] );
Aici puteți vedea și de unde provine numărul fracționar: Este transmis ca argument pentru a identifica transientul.
Nimic de care să vă îngrijorați.

Dacă dorești să protejezi fișierul, poți restricționa accesul la acesta prin fișierul tău httpd.conf (fișierul de configurare global Apache).
# Fișierul Wordpress wp-cron.php
<Files "wp-cron.php">
Require ip 1.2.3.4
</Files>
Înlocuiește IP-ul din exemplu cu adresa IP a serverului tău. Aceasta va permite în continuare accesul la fișier de pe server folosind o comandă precum:
wget -q -O - domeniu.com/wp-cron.php?doing_wp_cron
Și va returna un 403 (acces interzis pentru cererile de la orice alt IP). Dacă folosești o regulă suplimentară precum cea de mai jos, vei redirecționa cererile externe de la 403 Forbidden
către o altă pagină (cum ar fi pagina principală), lucru care nu este cu adevărat necesar.
ErrorDocument 403 https://www.domeniu.ro
Chiar mai bine, poți folosi Require ip 127.0.0.1
cu exemplul de mai sus și să folosești cererea wget: wget -q -O - 127.0.0.1/wp-cron.php?doing_wp_cron
. Aceasta va folosi controlerul de rețea loopback, iar cererea ta nu va fi trimisă în internetul public și înapoi.

care va bloca invocările din cron-ul OS care sunt de obicei făcute folosind wget

Puteți să-mi arătați unde este apelat wget în codul sursă. O căutare rapidă nu m-a ajutat să-l găsesc repede. Am găsit mai multe referințe la wget, dar doar în pluginurile WordFence și BulletProof.

WordPress nu folosește cron-uri OS. De asemenea, folosind regula de mai sus, am reușit să accesez wp-cron.php folosind wget atât cu wget http://localhost/wp-cron.php cât și cu wget http://127.0.0.1/wp-cron.php. Totuși, când am încercat să accesez din exterior, am primit următoarele în access_log "GET /wp-cron.php HTTP/1.1" 302 (redirecționare). Pentru că am și un ErrorDocument 403 https://www.domain.com/index.php care direcționează toate accesul interzis către pagina principală.

cron este solicitat prin HTTP din nucleul WordPress. Toate tutorialele disponibile pe internet sugerează să folosești wget pentru a declanșa WP cron din cron-ul sistemului de operare ca înlocuitor pentru declanșarea nativă a cron-ului în WP. În plus, filtrarea după IP, care este întotdeauna o strategie de eșuat, este și mai proastă în acest caz, deoarece atunci când muți site-ul, fie cron-ul va înceta să funcționeze și nu vei ști de ce, fie acele linii nu vor mai avea niciun efect.

Folosește 127.0.0.1 în loc de IP-ul public al serverului, așa cum am menționat în răspunsul meu.

WordPress nu folosește niciodată wget
pentru WP-Cron și dacă alegi să configurezi job-uri cron la nivel de sistem de operare, nu ar trebui să folosești wget
probabil. Acest răspuns este inteligent, dar nu merge destul de departe... ai putea restricționa accesul la wp-cron.php
, dar apoi să folosești fie WP-CLI, fie /usr/bin/php
pentru a-l apela local.
