web-dev-qa-db-fra.com

Empêcher l'exécution JavaScript avec JavaScript?

Dans un commentaire sur - cette question Affaire de la prévention XSS, @Dandavis a suggéré:

si votre script fonctionne en premier, il est facile de casser les scripts suivants

L'idée est de fournir une fuite qui empêche (Inline) JavaScript pour les navigateurs qui ne prennent pas en charge CSP.

Je sais qu'il est possible d'écraser les fonctions existantes, mais ce n'est pas clair pour moi comment cela fonctionnerait exactement. Y a-t-il une solution triviale que 100% empêche une autre exécution de script? Sinon, existe-t-il des solutions qui fonctionnent dans la plupart des contextes ou de la plupart des navigateurs (et des moyens de les contourner pour d'autres contextes/navigateurs)?

6
tim

Y a-t-il une solution triviale que 100% empêche une autre exécution de script?

Non je ne pense pas. Chaque balise de script s'exécute dessus, alors jeterais une erreur n'arrêterait pas le prochain script. alert et entreprise et peut-être syncronous AJAX vous viendra à l'esprit pour empêcher d'autres scripts d'exécution, mais qui enfrairont tout le navigateur.

Sinon, existe-t-il des solutions qui fonctionnent dans la plupart des contextes ou de la plupart des navigateurs (et des moyens de les contourner pour d'autres contextes/navigateurs)?

Eh bien, vous pouvez essayer de nuler toutes les variables globales en boucle sur les propriétés de la fenêtre. Ensuite, dans la théorie, les scripts n'auraient pas accès au DOM pour faire quoi que ce soit. Dans pratique, cela ne fonctionnera probablement pas bien que toutes ces propriétés ne sont pas écrits. Je doute qu'il serait possible de supprimer tout d'intérêt.

D'autres hacks possibles pourraient être d'essayer de détruire le document avant que d'autres scripts puissent courir, peut-être en utilisant document.write en quelque sorte. Ce serait dans le pays du comportement indéfini et des dragons.

Échantillon de code:

Tout le monde aime un bon échantillon de code, alors voici un exemple de charge utile que j'imagine être difficile à battre.

<iframe name="iwin"></iframe>
<script>
(function() {
    // Due to the name attribute on the iframe, iwin is now
    // an implicit global for the iframe's contentWindow.
    // It should not have been there before the tag was parsed,
    // and the name could be randomized.

    // For legacy IE, to make globals accessible (0_o).
    iwin.execScript && iwin.execScript();

    // PWND, we have new globals.
    var XMLHttpRequest = iwin.XMLHttpRequest;
})();
</script>
5
Alexander O'Mara

L'idée est de fournir une fuite qui empêche (Inline) JavaScript pour les navigateurs qui ne prennent pas en charge CSP.

N'oubliez pas que le CSP ne doit pas être utilisé comme première ligne de défense. Vous devez coder correctement par contexte pour prévenir les XSS dans votre application. Owsap a de bonnes informations à ce sujet.

Cela étant dit, le CSP peut être une bonne retombée pour rendre XSS beaucoup moins sérieux, si une vulnérabilité XSS (c'est-à-dire mal ou aucun codage de quelque part sur votre page) soit trouvée dans votre application et exploitée.

Je sais qu'il est possible d'écraser les fonctions existantes, mais ce n'est pas clair pour moi comment cela fonctionnerait exactement.

C'est très simple à faire. Par exemple, XMLHttpRequest = myFunction, ou XMLHttpRequest = null empêcherait les scripts d'utiliser XMLHttpRequest directement.

Le problème est que si un attaquant peut ne pas utiliser cette fonction particulière et si l'attaquant sait que vous le faites, il pourrait facilement utiliser une méthode alternative. Bien que cela peut être possible d'écraser Tous fonctions, il n'est pas recommandé comme solution fiable.

Y a-t-il une solution triviale que 100% empêche une autre exécution de script?

Si vous avez une erreur de syntaxe dans votre <script>, alors rien dans ce <script>...</script> va courir. Malheureusement, avec XSS, l'attaquant pourrait facilement démarrer un nouveau <script> cela fonctionnerait bien.

En outre, il y a beaucoup de façons d'injecter JavaScript en plus de <script>, par exemple <img onload> ou onerror.

À ma connaissance, vous ne pouvez pas arrêter de manière fiable tout le HTML suivant de contenant XSS Execution.

Sinon, existe-t-il des solutions qui fonctionnent dans la plupart des contextes ou de la plupart des navigateurs (et des moyens de les contourner pour d'autres contextes/navigateurs)?

Le support de navigateur de la version 1 csp est Commençant de l'obtenir bien et car csp a été conçu comme une sauvegarde de toute façon (non une première ligne de défense), vous peut être en mesure d'arrêter votre recherche Là-bas Savoir que le support du navigateur sera un problème de rétrécissement.

Cela étant dit, je pense que l'idée de remplacement des fonctions pourrait aller un long chemin vers le succès. IT semble comme ça pourrait fonctionner de manière fiable en théorie. Bien que cela ne soit pas recommandé, je pense que ce serait une étude intéressante. Je me demande comment il serait complexe de mettre en œuvre.

6
Bryan Field

J'ai écrit ce commentaire avec jQuery à l'esprit, puisqu'il est vraiment facile de casser accidentellement. Puisque le code côté client le plus compliqué (le type avec les vecteurs) utilise JQuery, Ajax commun et des modèles qui provoquent des vulnérabilités ne fonctionneront tout simplement pas sans elle.

Le modèle de sécurité de Javascript est basé sur la référence , ce qui signifie que si vous ne pouvez pas atteindre quelque chose, cela n'existe pas au code. Il y a quelques références non attendues telles que constructor.constructor("alert(666)")(), mais elles sont gérables parce que JS n'a tout simplement pas que de nombreux intégrés à offrir (comparés à PHP ou à la LIB). Si vous pouvez dissimuler ou détruire la référence, vous supprimez la capacité. Doug Crockford parle beaucoup à ce sujet , et dans le mode "use strict", Il est encore plus applicable sur un niveau granulaire.

  • Vous seriez mieux rediriger vers une page sans balises de script; une version non-JS ou "LOFI", si disponible.

  • Vous pouvez utiliser une iframe de taille 100% avec un sandbox attrib pour ré-servir la page sans script; Quelque chose que j'ai un signet à utiliser pour des tests de compat (simplifie simplement une nouvelle iframe, la tailles et définit le .src sur location.href). Tous les navigateurs ne soutiennent pas sandbox, vous pouvez donc vous voler Pierre de payer Paul si votre objectif est de limiter certains-comment surplombé XSS.

  • window.stop() fonctionne dans certains navigateurs (FF à coup sûr) et il est assez simple d'utiliser pour arrêter la page de chargement de la page.

  • "Brûlez les tous"; Clobber toutes les propriétés globales intégrées, laissant uniquement les capacités logiques pures de la langue derrière. L'inconvénient est que document n'est pas modifiable, ce qui est un adversaire intelligent vraiment besoin. Il peut y avoir un moyen facile de casser document, mais c'est un énorme vecteur tel d'être.

3
dandavis