XSLT et injections XSL

Aujourd’hui je vous propose un article un peu différent des autres puisqu’il sera purement théorique ! A l’origine je voulais le découper en deux parties, comme pour celui sur le XML et les XXE. Mais vu la tête de ma TODO list, je n’ai pas le temps de rentrer plus dans les détails pour cet article.

Donc nous allons parler du langage XSLT et plus particulièrement de la faille qui se cache derrière son utilisation. Le langage XSLT (pour eXtensible StyleSheet Language Transformations) est un langage de transformation qui permet de convertir un fichier XML en un document PDF, une page web ou encore un autre document XML.

Pour cela, on se sert d’un moteur XSLT. Ce moteur prend en paramètre deux fichiers : un fichier XML qui contiendra l’ensemble des données à traiter et un fichier XSLT dans lequel on trouvera le code de traitement. Voici comme invoquer ce moteur en PHP :

<?php

$xml_cod = new DOMDocument();
$xml_doc->load("xmltest.xml");

$xsl_doc = new DOMDocument();
$xsl_doc->load("xsltest.xsl");

$proc = new XSLTProcessor();
$prox->importStylesheet($xsl_doc);
$newdom = $proc->transofrmToDoc($xml_doc);

echo $newdom->saveXML();
?>

Concrètement, le XSLT ça ressemble à ça :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xls="https://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:for-each select="ordinateur/">
    	<h1>
      		Nom du PC:<xsl:value-of select="ordinateur/nom"/>
    	</h1>
    	<h3>
      		Spécifications :
    	</h3>
    	<br>
    	<p>Processeur : <xsl:value-of select="/ordinateur/processeur"/></p>
    	<p>RAM : <xsl:value-of select="/ordinateur/ram"/></p>
    	<p>Stockage : <xsl:value-of select="/ordinateur/stockage"/></p>
    	<p>Ecran : <xsl:value-of select="/ordinateur/ecran"/></p>
	</xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

On y retrouve des balises qui vont nous permettre de sélectionner des données :

<xsl:value-of select="objet à sélectionne"/>

Des balises qui nous permettront de boucler sur des données  :

<xsl:for-each select="ordinateur/">

Ou encore des balise qui nous permettront de créer des variables :

<xsl:variable name="variable" select="value" /> 

Après traitement de notre fichier XML (qui contient des données relatives aux spécifications d’ordinateurs), on obtiendrait plus ou moins ceci :

A priori le langage XSLT s’avère donc être plutôt utile… Seulement voilà, il existe une fonction qu’il ne faut absolument pas utiliser :

$xsl->registerPHPFunctions();

La fonction registerPHPFunctions() ! Pourquoi ? Eh bien parce qu’avec cette fonction activée, un attaquant pourrait utiliser une fonctionnalité avancée du XSLT : la gestion de code PHP !

Ainsi, un attaquant envoyant ce genre de balises sur votre application :

<xsl:value-of select="php:function('exec', 'ls -al /')"/>

Qui listerait l'ensemble des fichiers présents à la racine du serveur ainsi que les droits de ces derniers. Un attaquant pourrait donc supprimer des fichiers, en rajouter, injecter des webshell ou encore consulter le contenu de ces fichiers en utilisant cette balise :

<xsl:value-of select="document('index.php')"/>

Libre à lui d’étudier le code source de l’application pour ensuite lancer des attaques un peu plus puissante.

Il faut donc être très précautionneux si vous utilisez le langage XSLT. N’activez pas la gestion du PHP. Et si vous le faites, assurez vous que les inputs des utilisateurs de l’application soient nettoyés afin d’éviter tous problèmes