4

状況は次のとおりです。インタラクティブなダイアログを作成する JavaScript がいくつかあります (動的な要素の作成により、コミック ストリップの形式で表示されます... 楽しいです)。このページにより、ユーザーは設定を調整し、スクリプトによって生成されるダイアログを変更できます。理論的な例として、チェック ボックスの 1 つを "Use cussing" にすることができます。このボックスがオンの場合、スクリプトは返された文字列に cuss 単語のみを追加します。わかりました、十分に簡単です。楽しい。

現在、ダイアログを生成するために 1 つのテンプレートのみを使用しています (「コミック ストリップ」には非常に具体的で明確な目的があります)。このテンプレートは JavaScript にハード コードされています。ユーザーが独自のテンプレートを作成できるようにしたいと考えています。このテンプレートは、ハードコードされたバージョンと同じように実行されるスクリプトに変換され、チェックボックス オプションで制御することもできます。編集:明確にするために、ユーザーはスクリプトを直接記述しません。彼らは表現 (私は現在、JSON を使用することを検討しています) を記述し、他の誰かがテンプレートを使用してページを開くと、ページはそれをスクリプトに変換して実行します。

これにはいくつかの問題があります。最も明白なのは、悪意のあるユーザーによる攻撃です。編集:ユーザーは自分でスクリプトを作成することはありませんが、すべてがクライアント側であるため、私の解析スクリプトを簡単に見ることができ、何かを挿入する方法を理解できる可能性があります。ただし、これについてはあまり心配していません。編集を終了します。それに対処するための標準的な方法がいくつかあると確信しています.現在、サーバー側の相互作用はありません-すべてがクライアント側です. 現在、セット内にないすべての文字をグローバルに置き換えることにより、最初に文字列を単純に削除しています。

str.replace(/[^a-zA-Z...]/g,'').

もう 1 つの問題は、テンプレートを他のユーザーが楽しめるようにページに提供する方法です。私が言ったように、サーバー側の相互作用はありません。私はそれを維持したいと思います。テンプレートを保存するためにMySQLテーブルなどを作成したくありません。残念ながら、これは私が考えることができる唯一の実行可能な方法は、URL のクエリ文字列にテンプレートを含めることであることを意味します。やばい、それ。そして、それは文字の長さに制限を課します-私が正しく読んだ場合、古いIEと互換性があるのはわずか2,000です. (私はまた、HTMLファイルのテキストを生成して、コピーして貼り付け、そのまま保存し、どこかにホストし、URLで私のページにアドレスを送信し、それをiFrameにロードすることも考えました... Haユーザーフレンドリーではありません-ファイルタイプとして保存することと、

3 番目の問題は、ページがテンプレートを受け取って安全にし、スクリプトに変換した後、そのスクリプトをどのように実行すればよいかということです。Javascript を始めて以来、eval は悪だと聞いていたので、使用を避けてきました。どうやらやることnew Function(txt)は同じくらい悪いことです(私は以前に何度もやったことがありますが)。私はこれらの悪の主張を喜んで受け入れます.....しかし、どのような代替案がありますか?? 私はそれをGoogleで検索しましたが、私の状況に最も近いのは、リモートコードを含むこのStackOverflowの質問でした。受け入れられた回答は、スクリプト文字列に設定された textContent を使用してスクリプトタグを動的に作成することを提案しています。これも私にとって最良の解決策でしょうか?

概要

ユーザーが生成したテキストにアクセスし (できればサーバー側に保存せずに)、攻撃を回避しながら Javascript に解析し、eval().

  1. テンプレートを URL にクエリ文字列として保存し、それを共有できるようにすることは、テンプレートをページに取得する唯一の方法ですか?
  2. 知っておくべきセキュリティ ホールとは?悪意のあるユーザーから保護するための標準的な方法は?
  3. スクリプトにハードコードされていないコードをリモートで取得して実行するために、eval に代わるものはありますか?
4

1 に答える 1

3

@pst が言ったように、テンプレート機能 (および引数) の JSON 表現を使用し、信頼できるコードのみを実行します。

多分何かのような

{
  border: { color: '#BADA55' },
  layout: { columns: 2, rows: 4 }
}

次に、ループ、ハンドラーの配列、switch...caseカスケードなどで解析します。

少し圧縮すると、2000 文字未満の非常に詳細なテンプレートに収まります。


jsfiddle は、信頼できないコードを別のドメイン名から iframe に提供することで安全に実行します。そのため、これがオプションであり、信頼できないコードを本当に評価したい場合は、そうしてください。「傷ついた経験」を防ぐことを主張する場合でも、宣言的な表現を作成することになります(または、できないことに気付くまで完全にサニタイズしようとします)。

于 2012-06-01T21:09:37.040 に答える