Рассмотрим этот псевдокод:

(function(window){
   var options = { /*where everything goes */ };

   var instance = (function(options){
       for (var i in options){
       if (options.hasOwnProperty(i)){
         this[i] = options[i];
       }
     }
   })(options);

   instance.callbacks = function(cb){
     //...
   }

   instance.is_allowed = function()
    //... checks, return boolean
   }

   window.instance = instance;
})(this);

Если кто-то захочет манипулировать этим кодом (например, злонамеренный пользователь), он переписывает функцию is_allowed своей собственной, например, с использованием адресной строки (у него нет firebug, кто знает).

javascript:(function(){ window.instance.is_allowed = function(){ return true; } })();

Это наивный пример, но суть в том, что все в Javascript может быть перезаписано.

Я знаю, что в es5 у нас есть Object.defineProperty, поэтому вы можете установить:

// being explicit
Object.defineProperty(instance, "is_allowed", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: function(){
    // do checks
  }    
});

На самом деле, лучше всего в этом смысле использовать Object.freeze(instance) или Object.seal(instance) вместо Object.defineProperty, поскольку последнее можно снова вызвать с помощью writable: false (глупо, да?)

Есть ли ЛЮБОЙ способ, которым он работает в старых браузерах (а именно IE6-8) без особых хлопот? Если это невозможно, я просто пожму плечами и продолжу.

16
pocesar 3 Фев 2013 в 14:02

3 ответа

Лучший ответ

Если кто-то захочет манипулировать этим кодом (например, злоумышленник), он переписывает функцию is_allowed своей собственной

Он может переписать весь ваш код JavaScript или даже не использовать браузер, но имитировать запрос «без браузера» на ваш сервер.

Есть ли ЛЮБОЙ способ, которым он работает в старых браузерах (а именно IE6-8) без особых хлопот?

Нет. Все, что вы выставляете глобально, может быть изменено пользователем, браузеры ограничивают поведение javascript:, чтобы пользователи не были одурачены для доступа к предварительно созданным ссылкам. Firefox недавно внес некоторые изменения в протокол URL-адреса javascript.

Как сказано в этой статье: http://survey-remover.com/blog/javascript- протокол - опасности /

Что касается Chrome v13, Firefox v6 и IE 9, разработчики браузеров обратили внимание на опасность протокола «javascript:» и впоследствии запретили код ... В случае Chrome и IE подстрока «javascript:» удаляется при вставке кода, тогда как Firefox больше не выполняет сценарий в пределах активной страницы.

Так...

Если это невозможно, я просто пожму плечами и продолжу.

Вам следует.

2
Fagner Brack 5 Фев 2013 в 21:54

Предложение

Я не скажу, что я эксперт в этих вещах. Но предполагая, что вы можете полностью обернуть свой код и использовать события для запуска поведения, вы можете использовать такую структуру:

Closed = function(args) { return (function() {
  "use strict";

  var secret, init, get_secret, use_secret;

  init = function(something){
    secret = something;
  };

  get_secret = function() {
    return secret;
  };

  use_secret = function () {
    console.log(secret);
  };

  /* Run constructor */
  init(args);

  /* Publish API */
  return { use_secret:use_secret };

}())};

Настроив его с помощью obj = Closed("Anything");, вы все равно можете заставить злонамеренного пользователя перезаписать метод use_secret(), поскольку он открыт, но метод get_secret() и любые другие внутренние компоненты защищены.

Если ваш метод init объявляет несколько привязок событий к приложению, вы можете сохранить свое состояние таким образом. События смогут запускать внутренние методы, поскольку они связаны внутри внутреннего замыкания, но внешний код их не увидит.

Бронирование

Хотя это может решить вашу проблему, я не уверен на 100%, но в любом случае этому нельзя доверять. Любой пользователь, который хочет проникнуть в ваше приложение, может, пока безопасность на стороне клиента. Нет ничего, что могло бы помешать им создать свой собственный объект, чтобы заменить ваш по факту, ES5 или нет ES5.

Для всего, что действительно должно быть защищено, вам придется пройти повторную проверку на стороне сервера. Никогда не доверяйте клиентскому коду, чтобы защитить вас, запрос может даже не прийти со страницы, которую вы обслуживали ...

2
Jonas Schubert Erlandsson 3 Фев 2013 в 15:21

Что если is_allowed будет полностью локальным?

(function(window){
   var options = {}, is_allowed;

   var instance = (function(options){
     for (var i in options) {
     if (options.hasOwnProperty(i)) {
        this[i] = options[i];
       }
     }
     return this;
   })(options);

   instance.callbacks = function(cb){
       /* ... */
   };

   function check_allowed(){
     /* check and let this function set [is_allowed] */
   };

  window.instance = check_allowed()
                     ? instance
                     : { callbacks: function(){(alert('not allowed'));}  };

} (this) );

jsBin макет

Кстати: в вашем коде window.instance будет undefined.

0
KooiInc 4 Фев 2013 в 08:07