Prendi una delle soluzioni che seguono il modello privato o privilegiato di Crockford . Per esempio:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
In ogni caso in cui l'attaccante non ha diritto di "esecuzione" sul contesto JS, non ha modo di accedere a campi o metodi "pubblici" o "privati". Nel caso in cui l'attaccante abbia tale accesso, può eseguire questo one-liner:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Si noti che il codice sopra è generico per tutta la privacy di tipo costruttore. Fallirà con alcune delle soluzioni qui, ma dovrebbe essere chiaro che praticamente tutte le soluzioni basate sulla chiusura possono essere rotte in questo modo con replace()
parametri diversi .
Dopo che questo è stato eseguito, qualsiasi oggetto creato con new Foo()
avrà un eval
metodo che può essere chiamato per restituire o modificare valori o metodi definiti nella chiusura del costruttore, ad esempio:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
L'unico problema che posso vedere con questo è che non funzionerà nei casi in cui esiste solo un'istanza ed è stata creata al caricamento. Ma poi non c'è motivo di definire effettivamente un prototipo e in tal caso l'attaccante può semplicemente ricreare l'oggetto invece del costruttore purché abbia un modo di passare gli stessi parametri (ad esempio, sono costanti o calcolati dai valori disponibili).
Secondo me, questo rende praticamente inutile la soluzione di Crockford. Dal momento che la "privacy" si rompe facilmente, gli aspetti negativi della sua soluzione (leggibilità e manutenibilità ridotte, prestazioni ridotte, memoria aumentata) rendono il metodo basato sul prototipo "nessuna privacy" la scelta migliore.
Io di solito uso di sottolineatura per contrassegnare leader __private
e _protected
metodi e campi (stile Perl), ma l'idea di avere privacy in JavaScript solo mostra come si tratta di un linguaggio incompreso.
Pertanto non sono d'accordo con Crockford, fatta eccezione per la sua prima frase.
Quindi, come si ottiene la vera privacy in JS? Metti tutto ciò che è necessario per essere privato sul lato server e usa JS per fare chiamate AJAX.