Возьмите любое из решений, которые следуют частному или привилегированному образцу Крокфорда . Например:
function Foo(x) {
var y = 5;
var bar = function() {
return y * x;
};
this.public = function(z) {
return bar() + x * z;
};
}
В любом случае, когда злоумышленник не имеет права «выполнить» в контексте JS, у него нет возможности получить доступ к каким-либо «открытым» или «закрытым» полям или методам. Если у злоумышленника есть такой доступ, он может выполнить следующую однострочную строку:
eval("Foo = " + Foo.toString().replace(
/{/, "{ this.eval = function(code) { return eval(code); }; "
));
Обратите внимание, что приведенный выше код является общим для всех конструкторов-типов-конфиденциальности. Он потерпит неудачу с некоторыми решениями здесь, но должно быть ясно, что почти все решения, основанные на замыканиях, могут быть разбиты таким образом с другими replace()
параметрами.
После этого любой объект, созданный с помощью new Foo()
, будет иметь eval
метод, который можно вызывать для возврата или изменения значений или методов, определенных в замыкании конструктора, например:
f = new Foo(99);
f.eval("x");
f.eval("y");
f.eval("x = 8");
Единственная проблема, с которой я могу столкнуться, заключается в том, что она не будет работать в тех случаях, когда существует только один экземпляр, и он создается при загрузке. Но тогда нет никакой причины фактически определять прототип, и в этом случае злоумышленник может просто воссоздать объект вместо конструктора, если у него есть способ передать те же самые параметры (например, они являются постоянными или вычисляются из доступных значений).
На мой взгляд, это в значительной степени делает решение Крокфорда бесполезным.Поскольку «конфиденциальность» легко нарушается, недостатки его решения (сниженная читаемость и удобство обслуживания, сниженная производительность, увеличенная память) делают метод, основанный на прототипах «без конфиденциальности», лучшим выбором.
Я обычно использую начальные подчеркивания для обозначения, __private
а также для _protected
методов и полей (стиль Perl), но идея сохранения конфиденциальности в JavaScript просто показывает, как это неправильно понимается.
Поэтому я не согласен с Крокфордом за исключением его первого предложения.
Так как же получить настоящую конфиденциальность в JS? Поместите все, что требуется для приватности на стороне сервера, и используйте JS для выполнения вызовов AJAX.