Je me demande s'il est possible de sandbox JavaScript s'exécutant dans le navigateur pour empêcher l'accès aux fonctionnalités qui sont normalement disponibles pour le code JavaScript s'exécutant dans une page HTML.
Par exemple, disons que je souhaite fournir une API JavaScript aux utilisateurs finaux pour leur permettre de définir des gestionnaires d'événements à exécuter lorsque des "événements intéressants" se produisent, mais je ne veux pas que ces utilisateurs accèdent aux propriétés et aux fonctions de l' window
objet. Suis-je capable de faire ça?
Dans le cas le plus simple, disons que je veux empêcher les utilisateurs d'appeler alert
. Quelques approches auxquelles je peux penser sont:
- Redéfinissez
window.alert
globalement. Je ne pense pas que ce serait une approche valide car d'autres codes exécutés dans la page (c'est-à-dire des éléments non créés par les utilisateurs dans leurs gestionnaires d'événements) pourraient vouloir utiliseralert
. - Envoyez le code du gestionnaire d'événements au serveur à traiter. Je ne suis pas sûr que l'envoi du code au serveur à traiter soit la bonne approche car les gestionnaires d'événements doivent s'exécuter dans le contexte de la page.
Peut-être qu'une solution où le serveur traite la fonction définie par l'utilisateur puis génère un rappel à exécuter sur le client fonctionnerait? Même si cette approche fonctionne, existe-t-il de meilleures façons de résoudre ce problème?
la source
while (1) {}
--- il se bloque juste. De mêmea=[]; while (1) { a=[a,a]; }
.Jetez un œil à ADsafe de Douglas Crockford :
Vous pouvez voir un exemple d'utilisation d'ADsafe en examinant les fichiers
template.html
ettemplate.js
dans le référentiel GitHub du projet .la source
this
, ce qui est totalement inacceptable. Vous ne pouvez pas écrire du bon javascript sans utiliserthis
.this
. Il n'est pas difficile d'éviter le paramètre mal nommé.this
, il existe un non-this
moyen égal et équivalent de le faire (c'est juste un paramètre, après tout).J'ai créé une bibliothèque de sandboxing appelée jsandbox qui utilise des web workers pour sandbox évalué le code. Il dispose également d'une méthode d'entrée pour donner explicitement des données de code sandbox qu'il ne pourrait autrement pas obtenir.
Voici un exemple de l'API:
la source
Je pense que js.js mérite d'être mentionné ici. C'est un interpréteur JavaScript écrit en JavaScript.
Il est environ 200 fois plus lent que le JS natif, mais sa nature en fait un environnement sandbox parfait. Un autre inconvénient est sa taille - près de 600 Ko, ce qui peut être acceptable pour les ordinateurs de bureau dans certains cas, mais pas pour les appareils mobiles.
la source
Comme mentionné dans d'autres réponses, il suffit de mettre en prison le code dans une iframe en bac à sable (sans l'envoyer côté serveur) et de communiquer avec des messages. Je suggérerais de jeter un coup d'œil à une petite bibliothèque que j'ai créée principalement en raison de la nécessité de fournir une API au code non approuvé, comme décrit dans la question: il est possible d'exporter l'ensemble de fonctions particulier directement dans le bac à sable où le code non approuvé s'exécute. Et il y a aussi une démo qui exécute le code soumis par un utilisateur dans un bac à sable:
http://asvd.github.io/jailed/demos/web/console/
la source
Tous les fournisseurs de navigateurs et la spécification HTML5 travaillent sur une propriété sandbox réelle pour autoriser les iframes en sandbox - mais cela reste limité à la granularité iframe.
En général, aucun degré d'expressions régulières, etc. ne peut nettoyer en toute sécurité le JavaScript fourni par l'utilisateur arbitraire car il dégénère en problème d'arrêt: - /
la source
Une version améliorée du code sandbox des web workers de @ RyanOHara, dans un seul fichier (aucun
eval.js
fichier supplémentaire n'est nécessaire).Essaye-le:
https://jsfiddle.net/kp0cq6yw/
Il devrait sortir
6
(testé dans Chrome et Firefox).la source
Une manière moche mais peut-être que cela fonctionne pour vous, j'ai pris tous les globaux et les ai redéfinis dans la portée du bac à sable, ainsi que j'ai ajouté le mode strict afin qu'ils ne puissent pas obtenir l'objet global en utilisant une fonction anonyme.
https://gist.github.com/alejandrolechuga/9381781
la source
window
revenir de ça.sandboxcode('console.log((0,eval)("this"))')
function sbx(s,p) {e = eval; eval = function(t){console.log("GOT GOOD")}; sandboxcode(s,p); eval =e}
(_=>_).constructor('return this')()
Un interpréteur Javascript indépendant est plus susceptible de produire un bac à sable robuste qu'une version en cage de l'implémentation du navigateur intégré. Ryan a déjà mentionné js.js , mais un projet plus à jour est JS-Interpreter . La documentation explique comment exposer diverses fonctions à l'interpréteur, mais sa portée est par ailleurs très limitée.
la source
Depuis 2019, vm2 semble être la solution la plus populaire et la plus régulièrement mise à jour à ce problème.
la source
Avec NISP, vous pourrez faire une évaluation en bac à sable. Bien que l'expression que vous écrivez ne soit pas exactement un JS, vous écrirez plutôt des expressions s. Idéal pour les DSL simples qui ne nécessitent pas une programmation étendue.
la source
1) Supposons que vous ayez un code à exécuter:
Maintenant, supposons que vous souhaitiez l'exécuter dans un bac à sable:
Ces deux lignes une fois exécutées échoueront, car la fonction "alerte" n'est pas disponible depuis le "sandbox"
2) Et maintenant, vous souhaitez exposer un membre de l'objet window avec votre fonctionnalité:
En effet vous pouvez ajouter des citations s'échappant et faire d'autres polissage, mais je suppose que l'idée est claire.
la source
D'où vient ce JavaScript utilisateur?
Il n'y a pas grand-chose que vous puissiez faire pour qu'un utilisateur intègre du code dans votre page puis l'appelle depuis son navigateur (voir Greasemonkey, http://www.greasespot.net/ ). C'est juste quelque chose que font les navigateurs.
Cependant, si vous stockez le script dans une base de données, puis le récupérez et l'évaluez (), vous pouvez nettoyer le script avant qu'il ne soit exécuté.
Exemples de code qui supprime toutes les fenêtres. et document. références:
Cela tente d'empêcher l'exécution de ce qui suit (non testé):
Il existe de nombreuses limitations que vous devrez appliquer au script utilisateur non sécurisé. Malheureusement, il n'y a pas de «conteneur sandbox» disponible pour JavaScript.
la source
J'ai travaillé sur un bac à sable js simpliste pour permettre aux utilisateurs de créer des applets pour mon site. Bien que je fasse encore face à des défis pour autoriser l'accès au DOM (parentNode ne me laissera tout simplement pas garder les choses en sécurité = /), mon approche consistait simplement à redéfinir l'objet window avec certains de ses membres utiles / inoffensifs, puis à eval () l'utilisateur code avec cette fenêtre redéfinie comme portée par défaut.
Mon code "de base" va comme ça ... (je ne le montre pas entièrement;)
Donc, je peux créer une instance d'un Sandbox et utiliser son execute () pour faire fonctionner le code. De plus, toutes les nouvelles variables déclarées dans le code évalué seront finalement liées à la portée execute (), il n'y aura donc pas de conflits de noms ou de problèmes avec le code existant.
Bien que les objets globaux soient toujours accessibles, ceux qui doivent rester inconnus du code sandbox doivent être définis comme des proxys dans l'objet Sandbox :: scope.
J'espère que cela fonctionne pour toi.
la source
Vous pouvez envelopper le code de l'utilisateur dans une fonction qui redéfinit les objets interdits en tant que paramètres - ceux-ci seraient alors
undefined
appelés:Bien sûr, les attaquants intelligents peuvent contourner cela en inspectant le DOM Javascript et en trouvant un objet non surchargé qui contient une référence à la fenêtre.
Une autre idée consiste à scanner le code de l'utilisateur à l'aide d'un outil tel que jslint . Assurez-vous qu'il est défini pour ne pas avoir de variables prédéfinies (ou: uniquement les variables que vous voulez), puis si des globaux sont définis ou accédés, ne laissez pas le script de l'utilisateur être utilisé. Encore une fois, il peut être vulnérable à la marche dans le DOM - les objets que l'utilisateur peut construire à l'aide de littéraux peuvent avoir des références implicites à l'objet de fenêtre auquel il est possible d'accéder pour sortir du bac à sable.
la source