9

DOM の変更など、より強力な機能へのアクセスをユーザーに提供するのではなく、ユーザーにいくつかのスクリプト機能を提供したいと考えています。つまり、すべての入力/出力は、特定のインターフェイスを介してトンネリングされます。一種の制限された javacsript のように。

例: インターフェイスcheckanswer(func) が許可されている場合:

checkanswer( function (x,y)={
   return x+y;
}

ただし、これらは許可されていません。
alert(1)
document.write("hello world")
eval("alert()")

編集: 私が念頭に置いていたのは、 http: //stevehanov.ca/blog/index.php?id= 92 のような JavaScript を使用して実装された単純な言語でした。

4

8 に答える 8

13

(編集この回答は、編集前の質問に関連しています。Javascript を使用して実装されたスクリプト言語を知りませんが、いくつかあると思います。たとえば、ある時点で誰かが Javascript 用の BASIC を作成しました (以前はリンクがありましたが、したがって、この回答の残りの部分はかなり学術的なものですが、議論、説明、さらには注意の目的のために残しました. また、ボビンスのポイントに完全に同意し ます—これを自分で行わないでください, 作業を使用してくださいCajaなどの他のもの。)

ユーザーが生成したコンテンツでスクリプトを許可する場合は、保護メカニズムの穴を見つけて悪用する人々の軍拡競争に参加し、それらの悪用に対応するという事実に備えてください. 私はおそらくそれを避けると思いますが、あなたはあなたのコミュニティと虐待に対処するための選択肢を知っています. したがって、その準備ができている場合:

windowJavascript がシンボル解決を行う方法のため、 、documentActiveXObjectXMLHttpRequest、および同様のものが通常の意味を持たないコンテキストでスクリプトを評価できるように思われます。

// Define the scoper
var Scoper = (function() {
    var rv = {};

    rv.scope = function(codeString) {
        var window,
            document,
            ActiveXObject,
            XMLHttpRequest,
            alert,
            setTimeout,
            setInterval,
            clearTimeout,
            clearInterval,
            Function,
            arguments;
            // etc., etc., etc.

        // Just declaring `arguments` doesn't work (which makes
        // sense, actually), but overwriting it does
        arguments = undefined;

        // Execute the code; still probably pretty unsafe!
        eval(codeString);
    };

    return rv;;
})();

// Usage:
Scoper.scope(codeString);

(今は悪を使用していますevalが、を使用せずにクロスブラウザーのデフォルトオブジェクトをシャドウする方法をすぐには考えられませevalん。とにかくコードをテキストとして受け取っている場合...)

しかし、それは機能しません。これは部分的な解決策にすぎません (詳細は以下を参照)。コード内で(たとえば)codeStringアクセスしようとすると、グローバルではなくローカル変数にアクセスするというロジックがあります。他の人も同じです。残念ながら、シンボルが解決される方法により、 のプロパティは接頭辞 (たとえば )の有無にかかわらずアクセスできるため、それらもリストする必要があります。これは長いリストになる可能性があります。特に、bobince が指摘しているように、IE は名前または ID を持つ任意の DOM 要素を. したがって、おそらくこれをすべて独自の iframe に配置する必要があるため、その周りでエンドランを行うことができますwindowwindowwindowwindow.alertwindow問題と「のみ」は、標準のものに対処する必要があります。scopeまた、関数をオブジェクトのプロパティにした方法にも注意してください。その後、プロパティを介してのみ呼び出します。これでインスタンスthisに設定されScoperます (それ以外の場合、生の関数呼び出しではthisデフォルトでwindow! になります)。

しかし、ボビンスが指摘するように、物事を達成する方法は実にたくさんあります。たとえば、次のコードはcodeString上記の監獄をうまく破ることができます。

(new ('hello'.constructor.constructor)('alert("hello from global");'))()

さて、jailを更新してその特定のエクスプロイトが機能しないようにすることもできます (すべてconstructorの組み込みオブジェクトのプロパティをいじり ます) が、私はそれを疑う傾向があります。できれば誰か (ボブのような人) が次のような新しいエクスプロイトを考え出すでしょう:

(function(){return this;})().alert("hello again from global!");

したがって、「軍拡競争」。

これを行うための唯一の完全な方法は、適切な Javascript パーサーをサイトに組み込み、そのコードを解析して不正なアクセスをチェックしてから、コードを実行させることです。大変な作業ですが、ユースケースがそれを正当化する場合...

于 2010-04-20T08:54:32.547 に答える
5

TJ Crowder は、「軍拡競争」について優れた点を指摘しています。防水サンドボックスを構築するのは非常に困難です。

ただし、特定の関数を非常に簡単にオーバーライドすることは可能です。

シンプルな機能:

そして、この質問によれば、次のようなものをオーバーライドすることさえdocument.write簡単です

document.write = function(str) {}

サポートする必要のあるブラウザーでそれが機能する場合 (すべてのブラウザーで機能すると仮定します)、それが最善の解決策である可能性があります。

代替オプション:

  • スクリプトを別のサブドメインの IFrame にサンドボックス化します。独自の DOM を操作して alert() などを発行することは可能ですが、周囲のサイトはそのままです。選択した方法に関係なく、とにかくこれを行う必要がある場合があります

  • 許可された関数のホワイト リストを使用して、ユーザーのコードを解析します。非常に多くの記法とバリエーションがあるため、処理も非常に複雑です。

  • DOM の変更を監視する方法はいくつかありますが、Windows の DLL 管理と非常によく似た、変更をすぐに元に戻すメカニズムを構築できると確信しています。しかし、構築するのは非常に複雑で、リソースを大量に消費します。

于 2010-04-20T08:44:31.390 に答える
3

あまり。JavaScript は非常に動的な言語であり、多くの隠された機能やブラウザー固有の機能を備えており、これらを使用して、考案できるあらゆる種類の刑務所から抜け出すことができます。

これを自分で引き受けようとしないでください。Cajaなどの既存の 'mini-JS-like-language' プロジェクトの使用を検討してください。

于 2010-04-20T08:59:45.160 に答える
0

私は別の方法を手に入れました:Google Gears WorkerPool apiを使用
して
ください http://code.google.com/apis/gears/api_workerpool.html

作成されたワーカーは DOM にアクセスできません。ドキュメントやウィンドウなどのオブジェクトは、メイン ページにのみ存在します。これは、ワーカーが実行状態を共有していないためです。ただし、ワーカーはすべての JavaScript 組み込み関数にアクセスできます。自動的に定義されるグローバル変数 google.gears.factory を介して、ほとんどの Gears メソッドも使用できます。(1 つの例外は、DOM を必要とする LocalServer ファイル サブミッターです。) 他の機能については、作成されたワーカーがメイン ページに要求を実行するように依頼できます。

于 2010-04-23T03:25:20.313 に答える
0

Facebookと同じようにできます。すべての JavaScript ソースを前処理し、独自のラッパー API 以外のすべての名前にプレフィックスを追加しています。

于 2010-04-20T08:57:42.840 に答える
0

ユーザーが入力したデータを処理し、許可されたコンテンツのホワイト リストまたはブラック リストに基づいて無効なマークアップを置き換える必要があるようです。

于 2010-04-20T08:42:16.073 に答える
0

サンドボックスを実装するためにこのパターンはどうですか?

function safe(code,args)
{
    if (!args)
        args=[];
    return (function(){
    for (i in window) 
        eval("var "+i+";");
    return function(){return eval(code);}.apply(0,args);
    })();
}



ff=function()
{
    return 3.14;
}

console.log(safe("this;"));//Number
console.log(safe("window;"));//undefined
console.log(safe("console;"));//undefined
console.log(safe("Math;"));//MathConstructor
console.log(safe("JSON;"));//JSON
console.log(safe("Element;"));//undefined
console.log(safe("document;"));//undefined
console.log(safe("Math.cos(arguments[0]);",[3.14]));//-0.9999987317275395
console.log(safe("arguments[0]();",[ff]));//3.14

それは次を返します:

Number
undefined
undefined
MathConstructor
JSON
undefined
undefined
-0.9999987317275395
3.14 

このソリューションを攻撃するのに適したエクスプロイトを教えてください。もちろん、私の知識を理解し、改善するためだけに:)

ありがとう!

于 2012-07-16T22:46:44.760 に答える