0

Web ページに組み込まれた JavaScript パーサーに気付きました。ユーザーは、次のような JavaScript コードをテキスト領域に配置できます。

var i = 0;
i++;
var y = i * 10;
document.write(y);

これは、いくつかの出力 (例えば、document.write ストリームなど) を生成するために解析されます。

関数parseは、テキストエリア変更イベントが生成されたときに呼び出されます。

function parse(text) {
    try {
        ....
        eval(text);
    } catch (e) {
        ....
        return {
            status : false, output : ..., ... : ...
        };
    }
    return {
        status : true, output : ...., ... : ...
    };
}

すべて正常に動作しますが、アプリケーションがループに入るため、ユーザーがテキスト領域にループ (例: , )for(var i=0; i<10; )を書き込むと問題が発生します。while(true)

この問題を回避するために、この問題に対するいくつかの質問/解決策をお尋ねします。

  1. evalJavaScriptコードを許可するがループフリーのJavaScriptライブラリまたは関数はあり ますか?
  2. 解析関数を一定時間内に実行するように依頼できますか? そのような時間が経過すると、eval 関数を停止する例外が生成されます。
  3. を呼び出す前に、テキストを分析してやのようなパターンを探す関数をeval(text)呼び出すことができます。これは良い解決策ですか?これらのパターンを探すために正規表現を使用できますか?checkIfThereAreLoopsfor(var i=0; i<10; )while(true)
4

1 に答える 1

1

任意のコードが終了するかどうかを確認しようとしている場合、停止問題NP-Hardであるという大まかな時間に直面することになります。

したがって、安全でない入力をタイムアウトするか破棄する解析関数の予防策が必要であると考えるのは正しいことです。

ブラウザが「このスクリプトの実行時間が長すぎます」という制限を課さずに中断する方法を認識していないevalため、入力をサニタイズし、ループで何も評価しないようにする必要があります。 etc などの構造を検索してfor, while、再帰的な関数呼び出しを避けるだけです。

これは解決するのが難しい問題です...

「ハッキーな」解決策の 1 つは、入力されたコードの先頭に一意の変数宣言を挿入し (もちろん非表示)、この変数を入力コード内から 1 行おきにインクリメントすることです (ここでも、これらの挿入を非表示にして、構文構造がまた、増分ごとにサニティ チェックを挿入しますif unique_var > 99999 exit;(ここで、99999 は課す制限です)。

これにより、少なくとも無限ループが停止するはずです。

于 2013-03-21T09:42:12.497 に答える