10
votes

Faire de la boite de sable autour de la fonction () dans JavaScript

Puis-je limiter l'accès d'une fonction générée à la chaîne (à l'aide du constructeur de fonctions) aux champs parent / global?

Par exemple: le code suivant, tel qu'il est, imprime false em> , parce que la fonction stocke / modifie la variable A dans la fenêtre. p>

window.a = 4;
Function("a=3;")()
console.log(a === 4);


0 commentaires

4 Réponses :


6
votes

Je ne pense pas. Vous pouvez nommer les globaux que vous souhaitez protéger dans les paramètres afin qu'ils les tangent: xxx

mais la fonction va avoir accès à global, quoi que vous essayiez ... c'est pourquoi c'est pourquoi c'est pourquoi il est appelé Global.

Selon ce que vous essayez de faire, il existe d'autres autour de Work-autour de Workers ... et comme toujours, Hacks Hidden Iframe Hacks .


9 commentaires

Eh bien, vous pouvez définir fenêtre et document comme paramètres, pour empêcher leur accès direct (comme vous l'avez déjà dit), puis prépendez 'Utiliser strict'; au code pour empêcher la définition implicite des globaux. Cela pourrait fonctionner. Mais bien sûr, il n'empêche pas l'accès aux globaux existants tant que vous ne les «shadulez» par des paramètres. Peut-être pourrait-on itération sur toutes les propriétés window et créer la liste des paramètres automatiquement.


@Felixkling sonne bien à la valeur de visage, je vais essayer quelques hacks pour voir si je peux toujours avoir accès à Global


@Felixkling Voici mon article actuel, pourrait fonctionner si vous ombres fonction jsfiddle.net/dfmydleight " a>


Création des paramètres de la fenêtre S semble fonctionner: jsfiddle.net/lz2bc.


@Felixkling Même si une fonction tangée , nous avons toujours (fonction () {}). Constructeur


Vrai ... Eh bien, ce n'est pas parfait bien sûr, mais c'est quelque chose;) Les travailleurs du Web sont une bonne idée aussi!


Ensuite, il y a toutes sortes de littéraux: "". Constructor.constructor === Fonction ... Si on supprime tous ceux-ci, au moins chrome, la ré-supprimation les apporte: D


Regardez ma réponse pour une solution à cela :) (J'espère que ça marche: - /)


Vous pouvez réellement ombrager tous les globaux en les obtenant avec Object.getownPropertyNames (auto) et Fonction appelante.apply (...) ... Mais cela laisserait toujours le mot-clé «Ce», qui sera toujours égal à la portée mondiale. Et il est illégal d'avoir un argument nommé "ceci". Donc, cette truc d'observation ne peut fonctionner que avec le code transmis à Eval (), non fonction (), qui exécute toujours un code dans la portée globale au lieu de local.



2
votes

La réponse d'Esaija a raison. De plus, je vous recommanderais de limiter le nombre de variables globales que vous devez protéger en premier lieu. Mettez tout ce que vous seriez normalement placé dans l'espace de noms global dans une application que vous contrôlez: xxx

Il n'y a aucun moyen de limiter complètement l'accès à la portée globale, mais Au moins de cette façon, vous n'avez besoin que de protéger un objet: app .


0 commentaires

12
votes

Voici une idée supplémentaire qui pourrait être assez puissante avec la proposition d'Esaija (voir les commentaires sur sa réponse pour la discussion).

Vous pouvez créer une iframe factice et utiliser sa fonction fonction . La fonction créée avec cela n'aura qu'un accès à la portée de l'IFrame par défaut, bien qu'elle puisse toujours en sortir. Heureusement, il est facile d'empêcher que, par la façon dont Esaysaija suggère.

Je pouvais imaginer que la fonction est comme ceci: xxx

démo

éventuellement, vous pouvez éventuellement préparer 'Utiliser strict'; au code.


Cela fonctionne au moins en chrome. Si la fonction créée de cette manière a accès à la portée globale de l'iframe ou à la portée globale de la page peut être facilement testée avec: xxx


2 commentaires

Très créatif: D +1 I GET :) TO IE8, où il lance un ne prend pas la fonction de propriété ou de méthode


@Esailija: Merci d'avoir testé (je n'ai pas à savoir). Peut-être que la source de l'iframe doit être définie explicitement dans IE ( image.src = 'à propos de: vide' devrait faire) ou la propriété est simplement nommée différemment (pas contentwindow ). Si vous devez définir la source, vous devez peut-être attendre l'événement avant de pouvoir accéder à la fenêtre, mais bien sûr, il n'est pas possible de faire Sandboxed Accepter un rappel pour le résultat :)



1
votes

Voici mon Sandboxed code> Sandboxed. Il prend du code et un dictionnaire optionnel avec des arguments vers la fonction.

function sandboxed(code, args = {}) {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    var F = frame.contentWindow.Function;
    document.body.removeChild(frame);
    return F(...Object.keys(args), "'use strict';" + code)(...Object.values(args));
}

console.log(sandboxed('return a - 10;', {'a': 34}));

// 24


0 commentaires