WordPress 7.1.4 corregge 22 falle, tra cui una RCE durante l’aggiornamento
WordPress 7.1.4 è stato rilasciato il 28 ottobre 2026 con correzioni per 22 vulnerabilità trattate in 17 avvisi di sicurezza. La precedente versione 7.1.3 aveva risolto sette falle tre settimane prima. La maggior parte dei problemi appena corretti richiede un account esistente, solitamente con accesso Contributor o superiore, ma una race condition poteva portare alla remote code execution senza autenticazione. Una race condition è una falla che dipende dal verificarsi di azioni in una sequenza ristretta e non prevista, mentre remote code execution, o RCE, significa indurre un server a eseguire codice controllato dall’attaccante.
WordPress ha pubblicato lo stesso giorno backports, ossia correzioni adattate ai rami software meno recenti, per ogni ramo supportato fino alla versione 4.7.39. Le versioni disponibili includono 7.0.8, 6.9.11, 6.8.12, 6.7.11, 6.6.11, 6.5.14 e 6.4.14, con ulteriori backports fino alla 4.7.39. I siti che eseguono WordPress 4.6 o versioni precedenti non ricevono alcun aggiornamento. WordPress 7.1.4 è disponibile tramite Dashboard, Aggiornamenti e WordPress.org, mentre i siti con gli aggiornamenti in background abilitati dovrebbero installarlo automaticamente.
L’analisi del codice condotta da Patchstack ha rilevato che la falla con le conseguenze più rilevanti si trovava nel processo di aggiornamento del core. Durante un’installazione o un aggiornamento, WordPress estrae un pacchetto in wp-content/upgrade/, una directory che potrebbe essere resa pubblicamente accessibile dal web server. Prima della versione 7.1.4, la cartella estratta ereditava il nome del pacchetto, rendendone prevedibile la posizione per i pacchetti caricati tramite l’area di amministrazione. La pulizia iniziale rimuoveva inoltre tutto ciò che si trovava nella directory di aggiornamento, compreso il file index.php che impedisce ai visitatori di visualizzare un directory listing.
Per i pochi secondi necessari a completare un aggiornamento, i file estratti potevano quindi formare un’installazione WordPress completa a un indirizzo intuibile e potenzialmente esplorabile. Tale copia includeva wp-admin/setup-config.php, che poteva avviarsi in modo indipendente senza la configurazione del sito attivo. Un attaccante che fosse riuscito a raggiungerla durante la finestra di aggiornamento avrebbe potuto eseguire l’installer usando un database sotto il proprio controllo, pur rimanendo all’interno del document root del sito della vittima, ossia la cartella accessibile dal web che contiene il sito. Non erano richiesti né un account né l’interazione di un utente, sebbene i requisiti relativi alle tempistiche e all’esposizione rendessero difficile lo sfruttamento.
WordPress 7.1.4 aggiunge 16 caratteri casuali al nome della cartella temporanea, ripristina index.php e non elimina più tale file. Patchstack ha inoltre individuato una modifica separata a update-core.php che impedisce che wp-config.php venga copiato fuori dalla directory di lavoro. Patchstack ha classificato la falla come AC:H, indicando un’elevata complessità dell’attacco, e ha affermato che non era pratico sfruttarla. Ciononostante, il meccanismo vulnerabile risaliva a WordPress 2.8 e si ripresentava durante ogni aggiornamento, compresi quelli non presidiati.
Un firewall implementato in PHP, il linguaggio di programmazione in cui viene eseguito WordPress, non può intercettare questa specifica richiesta. Patchstack spiega che la copia estratta carica i propri file WordPress, mentre l’archivio ufficiale non contiene una directory mu-plugins per i plugin caricati automaticamente; di conseguenza, il firewall PHP del sito attivo non viene mai avviato. La mitigazione consigliata a livello di server consiste nel negare l’accesso web a wp-content/upgrade/ e nel verificare che i visitatori non possano esplorarne il contenuto. Tra un aggiornamento e l’altro, tale directory dovrebbe contenere soltanto index.php.
Sette avvisi riguardano la Interactivity API, la funzionalità di WordPress che consente agli elementi delle pagine di reagire ai visitatori. KSES, il sistema di filtraggio che controlla quale HTML possono salvare gli utenti privi del permesso unfiltered_html, consentiva qualsiasi attributo data-* e qualsiasi valore. Le direttive di interattività usano tali attributi, quindi gli utenti Contributor potevano inserire nei post direttive che superavano il filtraggio e venivano poi eseguite dal runtime lato browser quando qualcuno visualizzava la pagina. Le falle risultanti includevano stored cross-site scripting, o stored XSS, in cui codice dannoso per il browser viene salvato nei contenuti del sito e successivamente distribuito ai visitatori.
I problemi della Interactivity API riguardavano link javascript:, binding di event handler già rifiutati dal lato PHP, chiavi riservate come __proto__ inserite in un context merge, binding non sicuri su elementi object e un CSS parser che elaborava ripetutamente il proprio input. Il caso relativo al CSS poteva bloccare la scheda del browser di un visitatore, ma non esauriva le risorse del server. Altri avvisi riguardavano elementi object che caricavano pagine di amministrazione, prototype pollution e stored XSS insieme a denial of service nei binding. La versione 7.1.4 fa sì che KSES rimuova i binding che potrebbero modificare un valore convalidato in precedenza, limita i binding degli elementi object nel processore di direttive PHP e fa in modo che il runtime client rifiuti target non sicuri. Poiché il runtime client è stato introdotto nella versione 6.4 e la classe PHP è arrivata con la 6.5, WordPress indica entrambe le versioni come interessate dallo stesso numero di problemi.
Una falla correlata di state-shadowing si verificava perché la Interactivity API usava getElementById() per trovare uno script contenente il proprio stato. Tale funzione restituisce il primo ID corrispondente indipendentemente dal tipo di elemento, e WordPress inseriva lo script legittimo in wp_footer dopo il contenuto del post. Un Contributor poteva quindi inserire nei contenuti salvati un elemento precedente con lo stesso ID e fornire uno stato al runtime. WordPress 7.1.4 ora verifica che l’elemento selezionato sia effettivamente uno script. Un altro problema dell’Interactivity Router consentiva stored XSS tramite file di testo caricati e richiedeva un account di livello Author con il permesso di caricare file.
Sono stati corretti anche due problemi del Customizer. Selective refresh considerava attendibili gli attributi data-customize-partial-* provenienti dai contenuti visualizzati in anteprima e passava un selettore controllato dall’attaccante alla funzione $() di jQuery. jQuery interpreta una stringa che inizia con un segno di minore come HTML da creare, anziché come un selettore da cercare. WordPress ora usa .find(), che elabora soltanto selettori. Separatamente, una richiesta anonima di anteprima priva di un changeset UUID poteva adottare il changeset non pubblicato più recente, indipendentemente dal suo autore, esponendone l’UUID e l’anteprima renderizzata. La modifica delle impostazioni rimaneva protetta da permessi separati. La correzione richiede la capability customize.
Diverse falle del block editor riguardavano contenuti interpretati nuovamente dopo il filtraggio. Il blocco Categories filtrava l’etichetta di un menu a discesa e la usava poi come format string di sprintf(), consentendo alle direttive di formattazione di espandersi successivamente. I blocchi Image e Playlist usavano testo corrispondente influenzato dall’attaccante come replacement di preg_replace(), dove PHP poteva espandere backreference come $0 e inserire markup in un attributo. Questi blocchi ora usano la HTML API. I blocchi Comments Pagination e Post Navigation Link non eseguivano l’escape dei propri attributi label. Un problema separato del blocco Categories, la correzione di hardening per Image e Playlist e le etichette senza escape richiedevano rispettivamente accesso Contributor, Author e Contributor.
Anche i parser del server e dell’editor di WordPress non concordavano sulla gestione degli spazi nei delimitatori dei blocchi. Il parser PHP riconosceva sei caratteri di spazio, mentre JavaScript accettava anche non-breaking spaces, diversi spazi Unicode e un byte order mark.