1. ホーム
  2. ジャバスクリプト

[解決済み】JavaScriptのeval()が悪でないのはどんなとき?

2022-04-15 14:13:48

質問

私は、ユーザーが入力した関数を解析するJavaScriptコードを書いています(スプレッドシートのような機能用)。数式を解析した後、私は ができた。 をJavaScriptに変換して実行します。 eval() を実行し、結果を得ることができます。

しかし、私はこれまでずっと eval() 評価されるコードがユーザーによって変更される可能性があるためです)。

では、どのような場合に使用してもよいのでしょうか。

どのように解決するのですか?

ご質問の前提である、eval()が"であることについて、少し触れておきたいと思います。 ということです。という言葉は、quot; プログラミング言語関係者が使う「"」は、通常「危険な」、より正確には「簡単そうなコマンドで多くの損害を与えることができる」ことを意味します。では、どのような場合に危険なものを使ってもいいのでしょうか?危険なものが何であるかを知っていて、適切な予防策をとっているときです。

要は、eval()の使い方における危険性を見てみましょう。他のものと同じように小さな危険はたくさん隠れているでしょうが、大きなリスク、つまりeval()が悪とされる理由は、パフォーマンスとコードインジェクションの2つです。

  • パフォーマンス - eval()はインタープリタ/コンパイラを実行します。もしあなたのコードがコンパイルされているなら、これは大きな打撃です。なぜなら、実行時間の途中で、おそらく重いコンパイラを呼び出す必要があるからです。しかし、JavaScript はまだほとんどインタプリタ言語なので、一般的なケースでは eval() の呼び出しは大きなパフォーマンス上の問題にはなりません (ただし、以下の私の特別な指摘を参照してください)。
  • コードインジェクション - eval()は、昇格した特権の下でコード列を実行する可能性があります。例えば、管理者/ルートとして実行されているプログラムは、ユーザからの入力を eval() したくはないでしょう、なぜならその入力は "rm -rf /etc/important-file" またはそれ以上のものになる可能性があるからです。繰り返しますが、ブラウザのJavaScriptにはこのような問題はありません。なぜなら、そのプログラムはどのみちユーザー自身のアカウントで実行されているからです。サーバーサイドのJavaScriptは、そのような問題を抱える可能性があります。

あなたの具体的なケースについてです。私が理解したところでは、あなたは自分で文字列を生成しているので、 "rm -rf something-important" のような文字列が生成されないように注意していれば、コードインジェクションのリスクはありません(ただし、この場合は 非常に難しい を使用すると、一般的なケースでこれを保証することができます)。また、ブラウザで実行しているのであれば、コードインジェクションのリスクはかなり小さいと思います。

パフォーマンスに関しては、コーディングの容易さと比較検討する必要があるでしょう。私の意見としては、数式を解析するのであれば、別のパーサー(eval()内のもの)を実行するよりも、解析中に結果を計算したほうがよいのではないかと思います。しかし、eval()を使ってコーディングする方が簡単かもしれませんし、パフォーマンスへの打撃はおそらく気づかないほどでしょう。この場合、eval()は時間を節約できる可能性のある他の関数よりも悪者ではないように見えます。