Faille XSS en JavaScript ?

a marqué ce sujet comme résolu.

Bonjour,

Un truc que je n’arrive pas à capter, est-ce qu’on peut générer une faille XSS, avec JavaScript ? donc sans PHP.

Je ne comprends pas encore comment fonctionne JS concernant cette faille.

premier exemple

Admettons que j’utilise la bibliothèque UAParser.js pour afficher les données de mon User Agent, j’affiche comme ça :

const uap = new UAParser();
const result = uap.getResult();

Texte : document.querySelector('#ua').innerText = escapeHTML(result.ua);

HTML

<span id="ua"></span>

document.querySelector('#ua').innerHtml = escapeHTML(result.ua);

Dans les deux cas, j’utilise :

function escapeHTML(str) {
	const div = document.createElement("div");
	div.appendChild(document.createTextNode(str));

	return div.innerHTML;
}

Si un attaquant change son User Agent en javascript:alert('test');, la faille va se créer ? ou alors les bibliothèques sont sécurisées ? comment savoir ? dois-t-on sécuriser nous même en amont ?

second exemple

On reste dans la même situation que le premier exemple, mais cette fois, sans bibliothèque, et là je récupère l’User Agent directement :

const userAgent = navigator.userAgent;

document.querySelector('#ua').textContent = escapeHTML(userAgent);

<span id="ua"></span>

  1. Dois-je utiliser un échappement de caractères ?
  2. Puis-je afficher directement via innerHtml ?
  3. Puis-je afficher directement via textContent ?

Il y a d’autre exemple, si j’affiche les données EXIF d’une image, ou si je récupère les données du navigateur pour les afficher, etc.

En vous remerciant pour votre lecture.

+0 -0

Hello,

Une faille XSS peut avoir lieu à n’importe quel moment dans du HTML/DOM, qu’il soit généré côté serveur via PHP/Python/Node ou côté client en JS importe peu : si le HTML injecté est vérolé, il y a une faille.

L’échappement dépendra donc de ta source de donnée : si tu lui fais confiance tu peux afficher le texte brut. Si c’est une donnée manipulable par une source externe (par exemple un utilisateur) il faut donc bien l’échapper avant de l’afficher.

Certains frameworks (Angular, React, etc.) ont ce comportement par défaut : tout texte injecté est "assaini", et si on veut injecter du HTML (que l’on idéalement considère sûr) il faut contourner le système. C’est globalement une bonne pratique : on moins est sûr d’être protégé, même si ça implique plus de calcul (potentiellement inutile).

La particularité d’une faille XSS est que, comme son exécution a lieu côté client, si les données qui causent la faille sont elles-mêmes extraites de ce même client… globalement ça revient à se hacker soi-même. 🙃

Ok, je vois.

Pour le JavaScript quelle serai la bonne méthode ? vu que j’utilise du code simple pour le moment, je pensais à rester en innerText

+0 -0

Tant que tu n’as pas besoin d’insérer du HTML, passer par innerText devrait faire le job sans problème.

Sinon tu peux voir ce qu’utilisent les principaux frameworks, par exemple Angular (qui prend pas mal de précautions vu les différents usages possibles).

viki53

et pour le html tu conseillerai quoi ?

concernant Angular (ou les autres), j’ai déjà essayé de regarder, mais c’est un peu trop le fouillis, trouver une fonction dans ce tas de code, c’est difficile :D

+0 -0

J’ai pas trop eu le cas d’afficher du HTML via du JS côté client (autre que des données fournies par l’utilisateur lui-même), donc je ne saurais trop te dire, mais il existe des packages comme sanitize-html que j’utilise avec Node.js qui devraient faire le job côté client aussi (avec toujours le problème de performances et de la séparation des responsabilités : c’est avant tout au serveur de s’occuper de nettoyer les données).

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte