[JS] la beauté de l'attribut rel

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 :slight_smile:
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)

Sympa, mais est-ce exploitable? Je n’utilise la balise rel qu’en dur, sans contenu issu de variables, et donc encore moins de contenu utilisateur.

Bah c’est tellement exploitable que j’ai utilisé cette technique pour mettre le tag de MediaMetrie sur notre lecteur (mon soucis provenait du fait que je devais déclencher ce script que pour certaines vidéos et que pour certains actions, d�??où mon placement du code sur des qui intéressait)

un lien de prod pour démontrer que ça marche ? http://www.myskreen.com/tv-en-direct/89-public-senat

ouvre la source avec firebug et tu verras le code dans la balise rel du lien de cette chaine, j’ai viré l’alerte en prod (ofc) mais je peux t’assurer que Mediamétrie reçoit bien nos informations :wink:

C’est super moche :(. You fail at semantics. Utilise les extensions data pour ca.

Voir même pire. Ton code JS ne devrait JAMAIS être dans le fichier HTML.

c’etait un exemple rapide hein :wink:

(et je suis pas responsable du codage initiale de la page :x)