私の Web アプリでは、任意の JavaScript オブジェクトを GET パラメーターとして受け入れたいと考えています。location.search
したがって、 と同様の方法で解析する必要がありますが、自己完結型のオブジェクト(オブジェクト リテラル、配列、正規表現、およびおそらくアクセスが制限された関数)のみeval
を作成したいと考えています。
var search =
location.search ?
decodeURIComponent(location.search).substring(1).split('&') :
['boo=alert(1)', 'filter={a: /^t/, b: function(i){return i+1;}}']
;
var params = {};
for (var i = 0, temp; i < search.length; i++){
temp = search[i].split('=');
temp = temp[1] ? temp : [temp[0], null];
params[temp[0]] = saferEval(temp[1]);
};
console.log(params);
グローバル変数へのアクセスをブロックする関数のバージョンを思いつきましたが、次saferEval
のような組み込み関数へのアクセスはブロックしませんalert()
。
var saferEval = function(s) {
'use strict';
var deteleGlobals =
'var ' +
Object.getOwnPropertyNames(window)
.join(',')
.replace(/(?:eval|chrome:[^,]*),/g, '') +
';'
;
try {
return eval(deteleGlobals + '(' + s + ');') || s;
} catch(e) {
return s;
};
};
私のjsFiddleを参照してください-alert(1)
コードが実行されます。
jsFiddle スクリプトにはアクセスできないことに注意してください。.top.location
?filter={a: /%5Cd+/g}
JSONを使用しますが、配列とオブジェクト内の任意の場所に正規表現が必要です。これらのオブジェクトをサーバーに送り返さないので、これを使用eval
してもセキュリティにそれほど害はありません...
グローバル名前空間と組み込み関数へのアクセスを許可せずに、文字列(JavaScript オブジェクトをエンコードする)をオブジェクトに変換するにはどうすればよいですか?
更新 - 有用な「任意の」オブジェクトのみが正規表現リテラルであることが判明しました...