Vu que j’ai étonné Kadmelia sur twitter, je vais expliquer ma découverte du jour (le code est en js pure, utilisez vos framework de votre coté)
<?php
$script='<script>alert("toto");</script>';
$scriptEncode=htmlentities($script);
?>
<div id="Container"></div>
<a id="Lien" href="javascript:document.getElementById('Container').innerHTML=document.getElementById('Lien').rel" rel="<?php echo $scriptEncode ?>">Click me !</a>
le click va lancer l’alerte
et oui le tout sans eval() avec des caractères encodés (mattez la source générée). Tout ça parce l’attribut rel a un comportement différent. Il est mis directement dans l’objet DOM.
Vous pouvez placer ce que vous voulez comme code, des des ils seront exécutés (lecteur flash ;)).
Il y a une faille tout de même. Et là faut ruser. L�??exécution de tout le script placé dans l’attribut rel se fait de maniere asynchrone, du coup si dans le script vous avez quelque chose comme ça :
$script='
<script>var test=0;</script>
<script src="htpp://www.autredomaine.com/ChangeTest.js"></script>
<script>alert(test);</script>';
(on dit que ChangeTest.js modifie la valeur de test, ok ;))
test restera à 0. Car le chargement de ChangeTest se fait de manière asynchrone et l�??exécution de l’alerte se fait avant la fin du chargement du fichier js.
Pour celà, il faut contruire un domscript
$script='
<script>var test=0;</script>
<script>
function loaded() {
alert(test)
}
var domscript = document.createElement(\'script\');
domscript.src = "htpp://www.autredomaine.com/ChangeTest.js";
domscript.onloadDone = false;
domscript.onload = function() {
if ( ! domscript.onloadDone ) {
domscript.onloadDone = true;
loaded();
}
};
domscript.onreadystatechange = function() {
if ( ( "loaded" === domscript.readyState || "complete" === domscript.readyState ) && ! domscript.onloadDone ) {
domscript.onloadDone = true;
loaded();
}
};
document.getElementsByTagName(\'head\')[0].appendChild(domscript);
</script>';
et là votre valeur test aura changé, comme le montrera l’alerte.
(pensez à virer les sauts de lignes par contre)