Puis-je demander à un navigateur de ne pas exécuter s dans un élément?

Est-il possible de dire aux navigateurs de ne pas exécuter JavaScript à partir de parties spécifiques d’un document HTML?

Comme:

...

Cela pourrait être utile comme fonctionnalité de sécurité supplémentaire. Tous les scripts que je veux sont chargés dans une partie spécifique du document. Il ne devrait pas y avoir de scripts dans d’autres parties du document et s’ils existent, ils ne devraient pas être exécutés.

OUI, vous pouvez 🙂 La réponse est: Politique de sécurité du contenu (CSP).

La plupart des navigateurs modernes prennent en charge cet indicateur , qui indique uniquement au navigateur de charger du code JavaScript à partir d’un fichier externe approuvé et d’interdire tout code JavaScript interne! Le seul inconvénient est que vous ne pouvez pas utiliser de code JavaScript en ligne sur toute votre page (pas seulement pour un seul

). Bien qu’il puisse y avoir une solution de contournement en incluant dynamicment le div à partir d’un fichier externe avec une stratégie de sécurité différente, mais je ne suis pas sûr de cela.

Mais si vous pouvez modifier votre site pour charger tout le code JavaScript à partir de fichiers JavaScript externes, vous pouvez désactiver le code JavaScript en ligne avec cet en-tête!

Voici un bon tutoriel avec exemple: Tutoriel HTML5Rocks

Si vous pouvez configurer le serveur pour qu’il envoie cet indicateur HTTP-Header, le monde sera meilleur!

Vous pouvez bloquer JavaScript chargé par , en utilisant l'événement beforescriptexecute :

   

Question intéressante, je ne pense pas que ce soit possible. Mais même si c’est le cas, il semblerait que ce soit un piratage.

Si le contenu de cette div n’est pas fiable, vous devez alors échapper les données côté serveur avant de les envoyer dans la réponse HTTP et de les afficher dans le navigateur.

Si vous souhaitez uniquement supprimer les balises et autoriser d'autres balises html, retirez-les simplement du contenu et laissez le rest.

Rechercher dans la prévention XSS.

https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

JavaScript est exécuté “inline”, c’est-à-dire dans l’ordre dans lequel il apparaît dans le DOM (si ce n’était pas le cas, vous ne pourriez jamais être sûr que certaines variables définies dans un script différent étaient visibles lorsque vous les avez utilisées pour la première fois) ).

Donc, en théorie, vous pouvez avoir un script au début de la page (premier élément ) qui regarde dans le DOM et supprime tous les éléments et les gestionnaires d’événements intérieur de votre

.

Mais la réalité est plus complexe: le chargement de DOM et de script se fait de manière asynchrone. Cela signifie que le navigateur garantit uniquement qu'un script peut voir la partie du DOM qui le précède (c'est-à-dire l'en-tête jusqu'à présent dans notre exemple). Il n'y a aucune garantie pour quelque chose au-delà (ceci est lié à document.write() ). Donc, vous pourriez voir la balise de script suivante ou peut-être pas vous.

Vous pourriez vous attendre à l'événement onload du document - ce qui garantirait que vous ayez tout le DOM - mais à ce moment-là, un code malveillant aurait déjà été exécuté. Les choses empirent lorsque d'autres scripts manipulent le DOM, y ajoutant des scripts. Il faudrait donc vérifier également chaque changement de DOM.

Donc, la solution @cowls (filtrage sur le serveur) est la seule solution qui peut être faite pour fonctionner dans toutes les situations.

Si vous souhaitez afficher le code JavaScript dans votre navigateur:

En utilisant JavaScript et HTML, vous devrez utiliser des entités HTML pour afficher le code JavaScript et éviter que ce code ne soit exécuté. Ici vous pouvez trouver la liste des entités HTML:

Si vous utilisez un langage de script côté serveur (PHP, ASP.NET, etc.), il existe très probablement une fonction qui échappe à une chaîne et convertit les caractères spéciaux en entités HTML. En PHP, vous utiliseriez “htmlspecialchars ()” ou “htmlentities ()”. Ce dernier couvre tous les caractères HTML.

Si vous souhaitez afficher votre code JavaScript de manière agréable, essayez l’un des surligneurs de code:

J’ai une théorie:

  • Enveloppez la partie spécifique du document dans une balise noscript .
  • Utilisez les fonctions DOM pour supprimer toutes les balises de script à l’intérieur de la balise noscript puis déballez son contenu.

Exemple de preuve de concept:

 window.onload = function() { var noscripts = /* _live_ list */ document.getElementsByTagName("noscript"), memorydiv = document.createElement("div"), scripts = /* _live_ list */ memorydiv.getElementsByTagName("script"), i, j; for (i = noscripts.length - 1; i >= 0; --i) { memorydiv.innerHTML = noscripts[i].textContent || noscripts[i].innerText; for (j = scripts.length - 1; j >= 0; --j) { memorydiv.removeChild(scripts[j]); } while (memorydiv.firstChild) { noscripts[i].parentNode.insertBefore(memorydiv.firstChild, noscripts[i]); } noscripts[i].parentNode.removeChild(noscripts[i]); } }; 
 body { font: medium/1.5 monospace; } p, h1 { margin: 0; } 
 

Sample Content

1. This paragraph is embedded in HTML

3. This paragraph is embedded in HTML

Sample Content in No-JavaScript Zone

Si vous souhaitez réactiver les balises de script ultérieurement, ma solution consistait à casser l’environnement du navigateur pour que tout script qui s’exécute génère une erreur assez tôt. Cependant, ce n’est pas totalement fiable, vous ne pouvez donc pas l’utiliser comme fonction de sécurité.

Si vous essayez d’accéder aux propriétés globales, Chrome lancera une exception.

 setTimeout("Math.random()") // => VM116:25 Uncaught Error: JavaScript Execution Inhibited 

Je écrase toutes les propriétés remplaçables sur la window , mais vous pouvez également l’étendre pour casser d’autres fonctionnalités.

 window.allowJSExecution = inhibitJavaScriptExecution(); function inhibitJavaScriptExecution(){ var windowProperties = {}; var Object = window.Object var console = window.console var Error = window.Error function getPropertyDescriptor(object, propertyName){ var descriptor = Object.getOwnPropertyDescriptor(object, propertyName); if (!descriptor) { return getPropertyDescriptor(Object.getPrototypeOf(object), propertyName); } return descriptor; } for (var propName in window){ try { windowProperties[propName] = getPropertyDescriptor(window, propName) Object.defineProperty(window, propName, { get: function(){ throw Error("JavaScript Execution Inhibited") }, set: function(){ throw Error("JavaScript Execution Inhibited") }, configurable: true }) } catch (err) {} } return function allowJSExecution(){ for (var propName in window){ if (!(propName in windowProperties)) { delete windowProperties[propName] } } for (var propName in windowProperties){ try { Object.defineProperty(window, propName, windowProperties[propName]) } catch (err) {} } } }