Aller au contenu

React2Shell : quand le framework de Meta ouvre la porte de vos serveurs aux attaquants

Avis d'expert

11 décembre 2025

L’une des bibliothèque JavaScript les plus utilisées, React et le framework Next.js sont cibles d’une vulnérabilité critique scorée au CVSS par la note maximale de 10.0. Cette faille dans le code source permet à un attaquant non authentifié de gagner directement un accès aux serveurs des applications.

Qu’est-ce que React et Next.js ?

Courbe d’utilisation de React, https://trends.builtwith.com/javascript/React

Qui est vulnérable ?

Analyse de la vulnérabilité

Pile d’exécution

Le chainage de différents défauts de protection du code avec une ligne vulnérable n’échappant pas correctement une entrée utilisateur permettent cette exécution de code à distance.

D’abord dans resolveServerReference :

var idx = id.lastIndexOf("#");

-1 !== idx && ((name = id.slice(idx + 1))

 

Ce code sépare le champ id sur le caractère ‘#’.

Puis, arrive la fonction vulnérable : requireModule avec l’appel à la fonction dans loadServerReference pour assigner la variable fn. Le code à l’origine de la vulnérabilité est moduleExports[metadata[2]].
Le problème réside dans l’accès à la variable entre double crochets : cela vérifie l’ensemble du prototype chain et pas seulement sa propriété.

Ainsi, si la payload est :

{id:'fs#constructor',bound:[]}

Cela donne le code suivant :

requireModule(['fs',[],'constructor'])

puis :

__webpack_require__('fs')['constructor'].

Enfin, la dernière ligne de code permettant la vulnérabilité se trouve dans fonction la

loadServerReference :
Return fn.bind.apply(fn, [null].concat(_ref)) ;

Cela passe le champ bound de la payload à fn.bind() et donc en argument du module passé dans le champ id.

Pour expliciter, dans la payload, le champ id représente le module et bound son argument. Or, pour que la vulnérabilité donne accès au serveur, le bound ne doit être vide afin d’éviter que cela retourne la fonction sans l’exécuter.

La requête post d’un attaquant doit ressembler à cela :

POST /formaction HTTP/1.1

Content-Type: multipart/form-data; boundary=----Boundary

------Boundary

Content-Disposition: form-data; name="$ACTION_REF_0"

------Boundary

Content-Disposition: form-data; name="$ACTION_0:0"

{payload}

------Boundary--

Où :

$ACTION_REF_0 Permet de déclencher le parsing metadata
$ACTION_0 :0  Permet d’avoir le JSON contenant le l’id (le module) et le bound (l’argument de la fonction).

Impact de vulnérabilité

Pouvez-vous avoir été ciblé ?

Remédiation

Auteur

PARTAGER L'ARTICLE

Découvrez nos actualités

En savoir plus sur nos expertises