[spip-dev] [Sécurité] Re:[spip-commit] r22264 - branches/spip-2.1/ecrire/public

Hello,

j'ai l'impression que ce commit est assez sérieusement chamboulant, puisque du coup le résultat des filtres n'est plus protégé par interdire_script et pose un problème de sécurité.

interdire_script est maintenant inséré après les filtres automatiques de traitement mais avant ceux manuellement insérés dans le squelette.

Du coup
[(#TEXTE)] n'est plus équivalent à [(#TEXTE*|propre)] écriture souvent utilisée pour insérer en fait un autre filtre avant propre.

J'ai cru au premier abord que cela permettait des injections de php triviales en se servant de propre pour passer à travers interdire_script.
C'est heureusement un peu plus compliqué car quand propre et typo sont appelés sans leur second argument $connect ils appliquent automatiquement un interdire_script.

https://core.spip.net/projects/spip/repository/entry/spip/ecrire/inc/texte.php#L368

Ce patch est là pour prendre en charge les vieux appels direct en PHP à propre() depuis l'espace privé.

Si jamais on a dans le squelette [(#TEXTE*|propre{''})] alors cela bypasse vraiment le interdire_script, et on peut faire un injection de PHP en écrivant dans un article :

Coucou
<html><script id="</html><html>" language="php">phpinfo();</script></html>

qui produit le code suivant
Coucou
<script id="
" language="php">phpinfo();</script>

qui pourra être interprété en sortie

En SPIP>=3 on a légitimement réduit la porté de ce patch :
http://zone.spip.org/trac/spip-zone/browser/core/branches/spip-3.0/plugins/textwheel/inc/texte.php#L575
pour éviter d'avoir 2 fois interdire_script qui s'applique dans les squelettes du public, et du coup la simple écriture

[(#TEXTE*|propre)]

devient injectable.

Au delà de cet exemple précis, je pense que le problème c'est qu'on applique interdire_script sur une partie du traitement, et ça laisse la porte ouverte à des injections du même type, qui passent à travers interdire_script et utilisent les filtres suivants pour transformer le code inoffensif en code malicieux.

Je viens d'essayer et le phpinfo n'est pas exécuté. As-tu un autre exemple ?

Committo,Ergo:Sum

Committo,Ergo:sum a écrit :

Si jamais on a dans le squelette [(#TEXTE*|propre{''})] alors cela bypasse vraiment le interdire_script, et on peut faire un injection de PHP en écrivant dans un article :

Coucou
<html><script id="</html><html>" language="php">phpinfo();</script></html>

qui produit le code suivant
Coucou
<script id="
" language="php">phpinfo();</script>

qui pourra être interprété en sortie

Je viens d'essayer et le phpinfo n'est pas exécuté. As-tu un autre exemple ?

Pardon, j'ai compliqué inutilement l'exemple en voulant bien faire, la version simplifiée

Coucou
<html><script </html><html> language="php">phpinfo();</script></html>

fonctionne chez moi et permet d'exécuter le script quand on a

[(#TEXTE|propre{''})]

dans le squelette.

Subtilité quand même, il faut qu'il y ait d'autre PHP dans la page, pour que process_ins soit bien 'php' au moment de servir la page, car on ne detecte que "<?php" dans le compilateur de SPIP.
C'est quasi tout le temps le cas sur un squelette dans la vie réelle grâce aux <INCLURE>, mais par exemple cela ne permet pas de faire fonctionner l'exemple sur un squelette basique en un fichier qui n'aurait que ce contenu.

Cédric

Je viens d'essayer avec le squelette ci-dessous sous SPIP sans aucun plugin, et phpinfo ne s'exécute pas:

essai2
<INCLURE{pied.html}>
<BOUCLE1(ARTICLES){id_article=3702}>
[(#TEXTE*|propre{''})]
</BOUCLE1>

Committo,Ergo:Sum

Au temps pour moi, j'avais mal testé.
Ok, il y a un pb, et je n'en suis pas totalement surpris car je me doutais bien que ce "interdire_scripts" excessif
(car je le rappelle il neutralise AUSSI des scripts légitimement produits par le compilateur) devait être la porte ouverte
à des choses mal écrites en aval.
Je réfléchis et envoie qq chose ASAP.

Committo,Ergo:Sum