16

次の疑似コードを検討してください。

(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)orObject.seal(instance)の代わりに使用することです。Object.definePropertywritable: false

古いブラウザー (つまり IE6-8) で手間をかけずに動作する方法はありますか? それが不可能なら、肩をすくめて先に進みます。

4

3 に答える 3

2

提案

私はこれらのことについて専門家だとは言いません。ただし、コードを完全にラップし、イベントを使用して動作をトリガーできると仮定すると、次のような構造を使用できます。

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であろうとなかろうと、彼らが独自のオブジェクトを作成してあなたのものを置き換えることを止めるものは何もありません.

実際に安全である必要があるものについては、サーバー側で再検証する必要があります。あなたを保護するためにクライアント側のコードを信頼しないでください。リクエストは、あなたが提供したページから来ないかもしれません...

于 2013-02-03T15:21:22.340 に答える
2

誰かがこのコードを操作したいと思った場合 (悪意のあるユーザーなど)、is_allowed 関数を独自の関数で書き直します。

彼はあなたの JavaScript コード全体を書き直すか、ブラウザーを使用することさえせずにサーバーへの「ブラウザーレス」リクエストをシミュレートすることができます。

古いブラウザー (つまり IE6-8) で手間をかけずに動作する方法はありますか?

いいえ。グローバルに公開するものはすべて、ユーザーが変更できますjavascript:。ユーザーがだまされて事前に作成されたリンクにアクセスするのを避けるために、ブラウザーが動作を制限する必要があります。Firefox は最近、javascript URL プロトコルに何らかの変更を加えました。

この記事で述べたように: http://survey-remover.com/blog/javascript-protocol-dangers/

Chrome v13、Firefox v6、および IE 9 の時点で、ブラウザー開発者は「javascript:」プロトコルの危険性に注意を払い、その後、コードを禁止しました... Chrome と IE の場合、「javascript:」部分文字列はコードが貼り付けられると削除されますが、Firefox はアクティブなページの範囲内でスクリプトを実行しなくなります。

そう...

それが不可能なら、肩をすくめて先に進みます。

あなたがすべき。

于 2013-02-05T21:54:32.027 に答える
0

What if is_allowed would be completely local?

(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 mockup

BTW: in your code, window.instance would be undefined.

于 2013-02-03T11:08:27.673 に答える