Introduction à JavaScript
JavaScript (JS) est un langage de script incontournable qui permet d'ajouter de l'interactivité aux pages web construites avec HTML et CSS. Ce guide couvre les bases de JS d'un point de vue sécurité informatique et montre comment ses fonctionnalités légitimes peuvent être détournées à des fins malveillantes.
Prérequis
- Notions de base en Linux
- Compréhension des applications web
- Connaissance du fonctionnement des sites web
Objectifs d'apprentissage
- Maîtriser les fondamentaux de JS
- Intégrer JS dans des documents HTML
- Exploiter les fonctions de dialogue
- Contourner les structures de contrôle
- Analyser les fichiers JS minifiés et obfusqués
Concepts fondamentaux
Variables
Les variables servent de réceptacles pour stocker des données. En JS, trois mots-clés permettent de déclarer une variable : var (portée fonction), let et const (portée bloc). Ces deux derniers offrent un contrôle plus fin de la visibilité des variables.
Types de données
Les principaux types en JS incluent : string (chaîne de caractères), number, boolean (vrai/faux), null, undefined, et object (qui englobe les tableaux et objets complexes).
Fonctions
Une fonction regroupe un bloc de code destiné à accomplir une tâche spécifique. Par exemple, pour afficher les résultats d'étudiants :
<script>
function displayScore(studentId) {
alert("L'étudiant n°" + studentId + " a réussi l'examen");
}
for (var idx = 0; idx < 50; idx++) {
displayScore(identifiants[idx]);
}
</script>
Boucles
Les boucles permettent d'exécuter un bloc de code de manière répétée tant qu'une condition reste vraie. Les types courants sont for, while et do...while.
function displayScore(studentId) {
alert("L'étudiant n°" + studentId + " a réussi l'examen");
}
for (var idx = 0; idx < 50; idx++) {
displayScore(identifiants[idx]);
}
Quiz
Quel terme désigne la possibilité d'exécuter un bloc de code plusieurs fois sous réserve d'une condition ?
Réponse : loop (boucle)
Premier programme JavaScript
JS est un langage interprété, ce qui signifie que le code s'exécute directement dans le navigateur sans compilation préalable. Voici un exemple illustrant les concepts clés :
// Message d'accueil
console.log("Bienvenue sur THM");
// Variable et type de données
let temperature = 42;
// Structure conditionnelle
if (temperature > 30) {
console.log("Il fait chaud aujourd'hui.");
} else {
console.log("La température est modérée.");
}
// Définition de fonction
function saluer(utilisateur) {
console.log("Bonjour, " + utilisateur + " !");
}
// Appel de la fonction
saluer("Alice");
Utilisation de la console Chrome
Pour tester du JS dans le navigateur, ouvrez Chrome, appuyez sur Ctrl + Shift + I, puis cliquez sur l'onglet Console. Collez l'exemple suivant :
let premier = 7;
let second = 8;
let somme = premier + second;
console.log("Le total vaut : " + somme);
Après avoir pressé Entrée, le résultat s'affiche dans la console.
Quiz
Si l'on remplace premier par 12, quelle sera la sortie ?
let premier = 12;
let second = 8;
let somme = premier + second;
console.log("Le total vaut : " + somme);
Réponse : Le total vaut : 20
JavaScript est-il compilé ou interprété ?
Réponse : interprété
Intégration de JavaScript dans HTML
JS interne
Le JS interne consiste à placer directement le code dans le document HTML, entre des balises <script>. Créez un fichier calcul.html :
<html lang="fr">
<head>
<title>Calcul interne</title>
</head>
<body>
<h1>Multiplication de deux valeurs</h1>
<p id="sortie"></p>
<script>
var multiplicand = 6;
var multiplicateur = 7;
var produit = multiplicand * multiplicateur;
document.getElementById("sortie").innerHTML = "Le produit vaut : " + produit;
</script>
</body>
</html>
JS externe
Le JS externe sépare le code dans un fichier portant l'extension .js. Créez d'abord operation.js :
var multiplicand = 6;
var multiplicateur = 7;
var produit = multiplicand * multiplicateur;
document.getElementById("sortie").innerHTML = "Le produit vaut : " + produit;
Puis créez calcul_externe.html :
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Calcul externe</title>
</head>
<body>
<h1>Multiplication de deux valeurs</h1>
<p id="sortie"></p>
<script src="operation.js"></script>
</body>
</html>
Vérifier le type d'intégration
Lors d'un test de pénétration, il est utile de vérifier si un site utilise du JS interne ou externe. Faites un clic droit sur la page, puis sélectionnez Afficher le code source. Un tag <script> possédant l'attribut src indique un fichier JS externe.
Quiz
Quel type d'intégration place le code JS directement dans le document HTML ?
Réponse : Internal (interne)
Quelle méthode est préférable pour réutiliser le JS sur plusieurs pages ?
Réponse : External (externe)
Quel attribut dans une balise <script> permet de référencer un fichier JS externe ?
Réponse : src
Exploitation des foncitons de dialogue
JS offre trois fonctions de dialogue intégrées : alert, prompt et confirm. Si elles ne sont pas utilisées avec précaution, elles peuvent être exploitées dans des attaques XSS.
La fonction alert
Affiche un message avec un bouton « OK ». Exemple dans la console : alert("Bienvenue !");
La fonction prompt
Ouvre une boîte de dialogue demandant une saisie utilisateur. Si l'utilisateur clique sur « OK », la valeur saisie est renvoyée ; sinon, la fonction retourne null.
saisie = prompt("Entrez votre identifiant :");
alert("Bienvenue " + saisie);
La fonction confirm
Affiche un message avec deux boutons : « OK » (retourne true) et « Annuler » (retourne false). Exemple : confirm("Voulez-vous continuer ?");
Abus malveillant
Un fichier HTML apparemment inoffensif peut contenir du JS nuisible. Par exemple, le fichier facture.html ci-dessous affiche une alerte 5 fois de suite :
<html lang="fr">
<head>
<title>Facture</title>
</head>
<body>
<script>
for (var compteur = 0; compteur < 5; compteur++) {
alert("Système compromis");
}
</script>
</body>
</html>
Un acteur malveillant pourrait facilement augmenter le nombre d'itérations à 500 ou plus, rendant le navigateur pratiquement inutilisable.
Quiz
Combien de fois le fichier facture.html affiche-t-il l'alerte ?
Réponse : 5
Quelle fonction affiche une boîte de dialogue pour recueillir la saisie de l'utilisateur ?
Réponse : Prompt
Si l'utilisateur saisit « BMW », que contiendra la variable marque ?
marque = prompt("Quelle est la marque de votre voiture ?");
alert("Bonjour " + marque);
Réponse : BMW
Contournement des structures de contrôle
Les structures de contrôle déterminent l'ordre d'exécution du code selon des conditions données.
Exemple pratique avec if-else
Créez un fichier majorite.html :
<html lang="fr">
<head>
<title>Vérification d'âge</title>
</head>
<body>
<h1>Vérification de majorité</h1>
<p id="msg"></p>
<script>
var utilisateurAge = prompt("Indiquez votre âge");
if (utilisateurAge >= 18) {
document.getElementById("msg").innerHTML = "Vous êtes majeur.";
} else {
document.getElementById("msg").innerHTML = "Vous êtes mineur.";
}
</script>
</body>
</html>
Contournement d'un formulaire de connexion
Si l'authentification est réalisée uniquement côté client via JS, il est possible de contourner la vérification en modifiant le code ou en manipulant les variables dans la console du navigateur.
Quiz
Quel message s'affiche si l'âge saisi est inférieur à 18 ans ?
Réponse : You are a minor.
Ouvrez le fichier de connexion (login.html) et inspectez le code source. Quel est le mot de passe de l'administrateur ?
Réponse : ComplexPassword
Fichiers JavaScript minifiés et obfusqués
Minification
La minification consiste à supprimer tous les caractères superflus (espaces, commentaires, sauts de ligne) et à raccourcir les noms de variables afin de réduire la taille du fichier.
Obfuscation
L'obfuscation va plus loin en renommant les variables et fonctions avec des identifiants incompréhensibles et en ajoutant du code parasite, rendant la lecture humaine extrêmement difficile.
Démonstration
Créez bienvenue.html :
<html lang="fr">
<head>
<title>Code obfusqué</title>
</head>
<body>
<h1>Démonstration d'obfuscation</h1>
<script src="bienvenue.js"></script>
</body>
</html>
Et bienvenue.js :
function demarrer() {
alert("Accueil THM");
}
demarrer();
Ouvrez bienvenue.html dans Chrome. L'alerte « Accueil THM » apparaît. En examinant l'onglet Sources des outils de développement, le code reste lisible.
Utilisez ensuite un outil d'obfuscation en ligne pour transformer ce code. Le résultat ressemble à ceci :
(function(_0x2a3f1b,_0x4c8d9e){var _0xf12a=_0x3b7c,_0x5d2e=_0x2a3f1b();while(!![]){try{var _0x8a1f=-parseInt(_0xf12a(0x4a))/(0x1+-0x1)*parseInt(_0xf12a(0x4b))/(-0x2)+parseInt(_0xf12a(0x4c))/(0x3)*parseInt(_0xf12a(0x4d))/(0x4)+parseInt(_0xf12a(0x4e))/(0x5)*parseInt(_0xf12a(0x4f))/(-0x6)+parseInt(_0xf12a(0x50))/(0x7);if(_0x8a1f===_0x4c8d9e)break;else _0x5d2e['push'](_0x5d2e['shift']());}catch(_0x3c9b){_0x5d2e['push'](_0x5d2e['shift']());}}}(_0x1a2b,-0x3e8f+0x4d2a));
function demarrer(){alert('\x41\x63\x63\x75\x65\x69\x6c\x20\x54\x48\x4d');}
demarrer();
Remplacez le contenu de bienvenue.js par ce code obfusqué. Rechargez la page : l'alerte s'affiche toujours correctement, bien que le code soit désormais illisible à l'œil nu.
Déobfuscation
Des outils en ligne permettent de retrouver le code lisible à partir du code obfusqué. Collez simplement le code dans un déobfuscateur pour récupérer la version originale.
Quiz
Quel message d'alerte s'affiche après l'exécution de bienvenue.html ?
Réponse : Welcome to THM
Quelle est la valeur de la variable age dans cet extrait obfusqué ?
age=0x1*0x247e+0x35*-0x2e+-0x1ae3;
Réponse : 21
Bonnes pratiques de sécurité pour JavaScript
Ne pas se fier uniquement à la validation côté client
Puisque l'utilisateur peut désactiver ou manipuler le JS dans son navigateur, toute validation critique (formulaires, authentification) doit impérativement être doublée côté serveur.
Vérifier les sources des bibliothèques
Évitez d'inclure aveuglément des scripts provenant de sources inconnues. Des bibliothèques malveillantes portant des noms proches de versions légitimes peuvent compromettre votre application.
Ne jamais coder en dur les secrets
N'incorporez jamais de clés API, jetons d'accès ou identifiants directement dans le code JS :
// Mauvaise pratique
const cleAPIPrivee = 'cle_THM_9876';
Ces données sont facilement accessibles via l'inspection du code source.
Minifier et obfusquer le code JS en production
La minification et l'obfuscation réduisent la taille des fichiers, accélèrent le chargement et compliquent la compréhension du code par un attaquant. Bien qu'un reverse engineering reste possible, cela augmente significativement le coût en temps et en effort.
Quiz
Inclure aveuglément du JS de n'importe quelle source est-il recommandé ? (oui/non)
Réponse : non