Fondamentaux de JavaScript pour la cybersécurité

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

Étiquettes: JavaScript HTML XSS web-security console-chrome

Publié le 5 août à 22h54