DataDome

Comment DataDome détecte l’évasion iframe de Puppeteer Extra Stealth

Table des matières

Qu’est-ce que Puppeteer Extra Stealth ?

Puppeteer Extra Stealth est un plugin qui améliore Puppeteer en ajoutant des fonctionnalités de furtivité avancées, rendant sa détection plus difficile. Il y parvient en masquant diverses caractéristiques du navigateur couramment utilisées pour identifier les bots, comme la modification des propriétés globales JavaScript et l’imitation de comportements humains.

Avec plus de 6 000 étoiles sur GitHub, il s’agit de l’un des outils les plus populaires pour créer des bots. Aujourd’hui, nous partageons l’une des méthodes de longue date de DataDome pour détecter Extra Stealth.

Comment DataDome détecte Extra Stealth

La bibliothèque Extra Stealth se compose de plusieurs modules appelés « évasions », chacun étant conçu pour contourner un vecteur de détection spécifique. Aujourd’hui, nous nous concentrerons sur l’évasion ciblant les objets de la fenêtre globale de l’iframe, connue sous le nom de iframe.contentWindow.

La création d’iframes initie un nouveau contexte d’exécution JavaScript, un processus complexe du navigateur qui, lorsqu’il est effectué par des navigateurs automatisés, laisse souvent des incohérences détectables.

Certaines de ces fuites sont simples, comme la présence de propriétés sur l’objet window de l’iframe, même après son retrait de la fenêtre principale. D’autres sont plus complexes, comme la présence inattendue d’objets résiduels après la suppression d’une iframe, ou la capacité d’exécuter du code JS dans le contexte de l’iframe avant l’API native utilisée par Puppeteer. L’évasion iframe.contentWindow d’Extra Stealth a été créée pour masquer ces fuites et empêcher la détection.

DataDome n’est pas dupe. Non seulement Puppeteer est détecté quoi qu’il arrive (par d’autres moyens non divulgués), mais nous sommes également capables de détecter l’utilisation de l’évasion Extra Stealth elle-même.

Cette méthode de détection côté client exécute du JavaScript dans le navigateur et envoie les résultats à DataDome pour évaluation. Le code ne fait que quelques lignes :

// Create an iframe

let iframe = document.createElement('iframe');
// Set its "srcdoc" property to any value
iframe.srcdoc = 'datadome';
// Insert the iframe into the DOM
document.body.appendChild(iframe);
// Detect the evasion
let detected = iframe.contentWindow.self.get?.toString();

Lorsque ce code est exécuté sur des navigateurs normaux, la variable detected sera vide.

Cependant, lorsqu’il est exécuté par des navigateurs automatisés avec Puppeteer Extra Stealth, cette variable aura une valeur très caractéristique :

PuppeteerExtraStealth_SourceCode

Ceci fait partie du code source réel d’Extra Stealth, avec des commentaires de ses développeurs. En raison d’une faille dans l’évasion, nos composants de détection côté client peuvent accéder à son code interne et le révéler.

Du point de vue de la détection, ce résultat est sans équivoque : en détectant cette valeur, DataDome peut facilement et précisément bloquer le bot.

De plus, puisque le code source d’Extra Stealth varie selon les versions, la valeur de la chaîne peut également identifier la version spécifique d’Extra Stealth utilisée. Cela peut servir de composant de signature pour évaluer l’ampleur de l’opération de botting.

Analyse détaillée de la méthode de détection

La raison pour laquelle cette vérification fonctionne est due à une erreur subtile dans le code source d’Extra Stealth. L’évasion iframe.contentWindow :

  • surcharge plusieurs API de navigateur pour orchestrer une instrumentation qui se déclenche lors de la création d’une iframe ;
  • lorsque cette instrumentation est déclenchée, elle remplace l’objet global de l’iframe par une simulation utilisant l’API Proxy de JavaScript, ce qui permet d’intercepter et de redéfinir des opérations fondamentales pour un autre objet.

La faille réside dans le gestionnaire du proxy, qui définit le comportement d’interception. Voici le code source d’Extra Stealth que nous avons vu précédemment, maintenant formaté :

 const contentWindowProxy = {
    get(target, key) {
    // Now to the interesting part:
    // We actually make this thing behave like a regular iframe window,
    // by intercepting calls to e.g. `.self` and redirect it to the correct thing. :)
    // That makes it possible for these assertions to be correct:
    // iframe.contentWindow.self === window.top // must be false
    if (key === 'self') {
        return this
    }
    // iframe.contentWindow.frameElement === iframe // must be true
    if (key === 'frameElement') {
        return iframe
    }
    // Intercept iframe.contentWindow[0] to hide the property 0 added by the proxy.
    if (key === '0') {
        return undefined
    }
    return Reflect.get(target, key)
    }
}

// …
const proxy = new Proxy(window, contentWindowProxy)

La variable contentWindowProxy contient le gestionnaire du proxy JavaScript. Voici la partie intéressante :

// Now to the interesting part:
// We actually make this thing behave like a regular iframe window,
// by intercepting calls to e.g. `.self` and redirect it to the correct thing. :)
// That makes it possible for these assertions to be correct:
// iframe.contentWindow.self === window.top // must be false
if (key === 'self') {
return this
}

L’auteur avait l’intention de lier la référence window.self = window, comme indiqué dans ses commentaires. Cependant, à ce stade de l’exécution, le mot-clé this ne pointe pas vers l’objet window simulé, mais vers l’objet gestionnaire du proxy lui-même.

Il aurait dû retourner le paramètre target de la méthode trap get() pour boucler correctement la référence window.self. En utilisant le mot-clé this, un chemin a été involontairement ouvert, exposant le contenu de l’objet gestionnaire.

Lors de la lecture de iframe.contentWindow.self.get, nous passons par le proxy de la fenêtre simulée vers le getter self, qui renvoie au gestionnaire, et finalement à la propriété .get, révélant ainsi la logique du piège.

Conclusion

Chez DataDome, nous développons continuellement des défis spécialisés pour détecter divers navigateurs headless et frameworks d’automatisation anti-détection. Ainsi, avec une seule exécution JavaScript, nous pouvons détecter les subtils effets secondaires introduits par ces outils, assurant une protection robuste contre le trafic automatisé.

Pour en savoir plus sur la manière dont DataDome peut protéger votre entreprise contre les bots les plus sophistiqués et la fraude en ligne, essayez gratuitement ou réservez une démo dès aujourd’hui.