Wybierz jedno z rozwiązań zgodnych z prywatnym lub uprzywilejowanym wzorem Crockford . Na przykład:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
W każdym przypadku, gdy atakujący nie ma prawa „wykonania” w kontekście JS, nie ma możliwości uzyskania dostępu do jakichkolwiek pól lub metod „publicznych” lub „prywatnych”. W przypadku, gdy atakujący ma taki dostęp, może wykonać jedną linijkę:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Zauważ, że powyższy kod jest ogólny dla prywatności wszystkich konstruktorów. Nie powiedzie się z niektórymi rozwiązaniami tutaj, ale powinno być jasne, że prawie wszystkie rozwiązania oparte na zamknięciu mogą zostać zepsute w ten sposób z różnymireplace()
parametrach.
Po wykonaniu tego każdy obiekt utworzony za pomocą new Foo()
będzie miał eval
metodę, która może zostać wywołana w celu zwrócenia lub zmiany wartości lub metod zdefiniowanych w zamknięciu konstruktora, np .:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
Jedyny problem, jaki mogę z tym zobaczyć, nie działa w przypadkach, w których istnieje tylko jedna instancja i jest tworzona podczas ładowania. Ale wtedy nie ma powodu, aby faktycznie definiować prototyp. W takim przypadku atakujący może po prostu odtworzyć obiekt zamiast konstruktora, o ile ma on możliwość przekazania tych samych parametrów (np. Są one stałe lub obliczane na podstawie dostępnych wartości).
Moim zdaniem dzięki temu rozwiązanie Crockforda jest bezużyteczne.Ponieważ „prywatność” jest łatwo łamana, wady jego rozwiązania (zmniejszona czytelność i łatwość konserwacji, zmniejszona wydajność, zwiększona pamięć) sprawiają, że metoda oparta na prototypach „brak prywatności” jest lepszym wyborem.
Ja zwykle korzystam wiodącym podkreślenia aby oznaczyć __private
i _protected
metod i pól (styl Perl), ale idea posiadania prywatności w JavaScripcie tylko pokazuje, w jaki sposób jest to język niezrozumiany.
Dlatego nie zgadzam się z Crockfordem wyjątkiem jego pierwszego zdania.
Jak więc uzyskać prawdziwą prywatność w JS? Umieść wszystko, co jest wymagane, aby być prywatnym po stronie serwera i używaj JS do wykonywania połączeń AJAX.