
Proof of concept locale sicuro per la vulnerabilità di iniezione di oggetti PHP in Cotonti CommentsWidget (CAN-2026-2035973 / CVE-2026-71294).
Proof of concept locale sicura per il problema di PHP object injection identificato nell'implementazione CommentsWidget di Cotonti.
plugins/comments/inc/CommentsWidget.phpIl percorso di codice vulnerabile accetta il parametro GET ci e passa dati controllati dall'attaccante attraverso base64_decode() in unserialize() di PHP senza limitare quali classi possono essere istanziate.
Concettualmente, l'operazione vulnerabile è:
$ci = @unserialize(base64_decode($ci));
Quando viene fornito un oggetto serializzato, PHP può istanziare la classe controllata dall'attaccante e invocare metodi magici come . In un'applicazione più ampia questo può diventare pericoloso quando sono disponibili classi gadget adatte.
__wakeup()La correzione proposta modifica la deserializzazione in:
$ci = @unserialize(base64_decode($ci), ['allowed_classes' => false]);
e convalida che il valore risultante abbia la struttura ad array attesa prima di utilizzarlo.
poc.php esegue tre test locali:
unserialize() senza restrizioni istanzia DangerousGadget e attiva il suo metodo __wakeup().allowed_classes => false impedisce l'istanziazione della classe gadget e quindi previene l'effetto collaterale di __wakeup().Il PoC utilizza /tmp/pwned_by_cotonti_poc.txt solo come sentinella innocua che dimostra che __wakeup() è stato eseguito. Non esegue un comando del sistema operativo. La stringa id && whoami esiste solo come valore segnaposto nella proprietà command del gadget.
serialize() / unserialize()Non è richiesta un'installazione di Cotonti perché il comportamento di deserializzazione vulnerabile e corretto viene riprodotto direttamente.
Dalla directory del repository:
php poc.php
L'output atteso è simile a:
[!] DangerousGadget::__wakeup() triggered
[TEST 1] VULNERABLE: __wakeup() executed during unrestricted unserialize().
[TEST 2] FIXED: object instantiation was blocked; no sentinel was created.
[TEST 3] FIXED: invalid serialized structure rejected by validation.
Summary:
- Vulnerable path allows a serialized attacker-controlled object to be instantiated and invokes __wakeup().
- Fixed path uses allowed_classes=false, preventing the gadget class from being instantiated.
- Structural validation rejects values that do not match the expected array shape.
- No real command execution is performed by this PoC; the command property is only a placeholder.
Lo script rimuove il suo file sentinella prima di terminare.
Non deserializzare dati controllati dall'attaccante con unserialize() di PHP senza restrizioni.
Per questo percorso di codice, la mitigazione dimostrata consiste nel disabilitare l'istanziazione delle classi:
unserialize($data, ['allowed_classes' => false]);
Il valore deserializzato dovrebbe anche essere convalidato rispetto alla struttura esatta attesa dall'applicazione prima che il suo contenuto venga utilizzato.
Questo repository è destinato alla ricerca sulla sicurezza, alla verifica e ai test difensivi. Esegui il PoC solo in ambienti che possiedi o che sei esplicitamente autorizzato a testare. Non utilizzarlo per attaccare sistemi senza autorizzazione.
Harsh Raj Singhania — ricerca sulla vulnerabilità, proof of concept e divulgazione.