Prenez l'une des solutions qui suivent le modèle privé ou privilégié de Crockford . Par exemple:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
Dans tous les cas où l'attaquant n'a aucun droit "exécuter" sur le contexte JS, il n'a aucun moyen d'accéder à des champs ou méthodes "publics" ou "privés". Dans le cas où l'attaquant a cet accès, il peut exécuter ce one-liner:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Notez que le code ci-dessus est générique pour tout constructeur-type-confidentialité. Cela échouera avec certaines des solutions ici, mais il devrait être clair que presque toutes les solutions basées sur la fermeture peuvent être cassées comme ceci avec différents replace()
paramètres.
Après cela, tout objet créé avec new Foo()
aura une eval
méthode qui peut être appelée pour retourner ou modifier des valeurs ou des méthodes définies dans la fermeture du constructeur, par exemple:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
Le seul problème que je peux voir avec cela est que cela ne fonctionnera pas dans les cas où il n'y a qu'une seule instance et qu'il est créé lors du chargement. Mais alors il n'y a aucune raison de définir réellement un prototype et dans ce cas, l'attaquant peut simplement recréer l'objet au lieu du constructeur tant qu'il a un moyen de passer les mêmes paramètres (par exemple, ils sont constants ou calculés à partir des valeurs disponibles).
À mon avis, cela rend à peu près la solution de Crockford inutile. Étant donné que la "confidentialité" est facilement brisée, les inconvénients de sa solution (lisibilité et maintenabilité réduites, performances réduites, mémoire accrue) font de la méthode basée sur le prototype "sans confidentialité" le meilleur choix.
J'utilise généralement des traits de soulignement principaux pour marquer __private
et les _protected
méthodes et les champs (style Perl), mais l'idée d'avoir la confidentialité en JavaScript montre simplement comment c'est un langage mal compris.
Je ne suis donc pas d'accord avec Crockford, à l' exception de sa première phrase.
Alors, comment obtenez-vous une réelle confidentialité dans JS? Mettez tout ce qui est nécessaire pour être privé côté serveur et utilisez JS pour faire des appels AJAX.