リスクも正しく把握! JavaScriptのevalで文字列をコードとして使おう

こんにちは、ライターのマサトです!

みなさん、eval()って知ってますか?文字列をJavaScriptのコードとして評価・実行できるものなのですが、ちょっとリスクがある関数でもあります。うっかりそれを理解しないまま使ってしまうと、大変なことになってしまうかもしれません。

この記事では

  • eval()はどのように使えるのか
  • リスクや代替方法

なども紹介していきます。もし過去に使ったことがある場合は、ぜひリスクに晒されていないかチェックしながら読んでみてください。

目次

「eval()」とは?

それでは、まず最初に「eval()」についての基本的な知識から学習を進めていきましょう!「eval()」は、一般的な文字列をJavaScriptのコードとして解析して実行することができます。

例えば、次のような文字列があるとします。

"alert('こんにちは')"

これはJavaScriptコードではなく、あくまで単純な文字列です。そのため、実行しても何も起きませんよね?

しかし、eval()を使うことでこの文字列がJavaScriptコードとして認識されて実行することができるわけです。本記事では、eval()の基本から注意するべき特性まで体系的に解説しているので、ぜひ参考にしてみてください!

「eval()」の使い方

この章では、eval()の基本的な使い方について学習をしていきましょう!もっとも基本となる構文や実際の実行例を学んでいきます。

「eval()」の基本的な構文と書き方

まずは、eval()の基本となる構文について見ていきましょう。eval()はグローバル関数なので、そのまま記述するだけでどこからでも利用することが可能です。

次の構文例を見てください!

eval( 文字列 )

eval()の構文は見ての通りとても単純で、引数に任意の文字列を指定するだけです。この文字列部分がJavaScriptコードである場合は、そのコードを解析して通常通り実行してくれます。

eval()で文字列をコードとして実行する方法

それでは、実際に文字列を指定して実行させてみましょう!例えば、何らかのメッセージを画面に表示する例は次の通りです。

var str = 'alert("こんにちは")';
      
eval( str );

この例では、「alert()」メソッドを使って文字列を画面に表示しています。alert()が文字列である点に注目してください!変数「str」に文字列を代入していますが、もちろんそのままeval()の引数に指定しても問題ありません。

eval()でJSONを扱う

この章では、eval()を使ったJSONの扱い方について学んでいきましょう!基本的なJSONの解析方法から、代替手段としてJSON.parse()についても学びます。

eval()を使ったJSONの解析方法

一般的にサーバーなどからJSONを受けとる場合、データは文字列になっています。そのため、そのままのデータだと扱いづらいのでJavaScript側でオブジェクト型に変換するのが一般的です。

そこで、eval()を使うとJSONを解析した結果をオブジェクト型にすることができます。例えば、次のようなJSON文字列があるとします。

{"name":"太郎","age":"30","tell":"090-1234-5678"}

3つのプロパティと値が設定された簡単なJSONデータです。eval()を使ってオブジェクト型にするには次のように記述します。(dataがJSONデータと考えてください)

var data = '{"name":"太郎","age":"30","tell":"090-1234-5678"}';
eval( 'var result =' + data );
console.log( result );

実行結果:

{name: "太郎", age: "30", tell: "090-1234-5678"}

eval()の引数に注目してください!文字列として「var result =」と記述し、そのあとにJSONデータと連結してますよね?

これにより、eval()がJSONを解析した結果を変数「result」に格納するという意味になります。このサンプル例を実行すると、コンソールにはオブジェクト化されたJSONが表示されます。

eval()の代替としてJSON.parse()を使う方法

さて、eval()でJSONを扱う方法を学びましたが、実は一般的にはこの方法はあまり使われません。

なぜなら、JSONをオブジェクト化するための専用のメソッドが標準で用意されているからです。それが「JSON.parse()」なのですが、ここで使い方を合わせて一緒に確認しておきましょう!

次のサンプル例を見てください!

var result = JSON.parse( data );


console.log( result );

この例では、「JSON.parse()」の引数にそのままJSONデータを設定しています。たったこれだけですが、コンソールにはオブジェクト化されたデータが表示されています。「eval()」「JSON.parse()」それぞれの使い方ができるように慣れておくと良いでしょう。

ちなみに、JSON.parse()のさらなる活用方法やその他のメソッドは次の記事でまとめているので参考にしてみてください!

eval()の危険性

この章では、eval()が持つ特性によってどんな危険性があるのかを見ていきましょう!eval()の性質や具体的なサンプルを通して理解しておくべきポイントを学びます。

eval()が持つ注意するべき性質について

まず最初に、eval()が持っている3つの性質について見ていきましょう!

  • パフォーマンス(処理速度の低下)
  • コードの乱雑性
  • セキュリティリスク

まず1つ目は「パフォーマンス」について。

eval()は、文字列をJavaScriptコードとして評価・解析する作業がどうしても必要です。そのため、普通にJavaScriptコードを書いた場合に比べて実行速度が「遅い」という欠点があります。

2つ目は「コードの乱雑性」です。

今回のサンプル程度なら問題はありませんが、引数に指定するコードが複雑になると問題が出てきます。つまり、デバッグ作業が非常に難しくなり、さらにeval()の中にeval()を追加するような複雑化すると解析が困難になるわけです。

3つ目は「セキュリティリスク」です。

eval()の特徴として文字列をJavaScriptコードに変換して実行できるという点が挙げられます。しかし、これは逆に第三者がコードを実行できてしまうリスクがあるわけです。この点については、次の章で具体的なコードと共に見ていきましょう!

入力フォームを使った危険な例

eval()のセキュリティリスクについて、最も基本的なサンプル例を見てみましょう!例えば、入力フォームなどを使って第三者から文字列を受けとる場合にeval()を使ってしまうと非常に危険です。

次のようなHTMLがあるとします。

<input id="text" type="text">
<button id="btn">ボタン</button>

これは、単純な入力フォームとボタンですね。そこで、eval()を使って入力された文字列を取得するプログラムを作ってみましょう!

var text = document.getElementById('text');
var btn = document.getElementById('btn');

btn.addEventListener('click', function() {
          var str = text.value;

          eval( str );
})

この例では、ボタンのクリックイベント処理を記述して、その中で入力された文字列をeval()で取得しています。つまり、入力フォームに文字列でコードを記述してボタンをクリックするとJavaScriptが実行されるというわけです。

これは第三者が好きなようにコードを実行できることを意味しており、Webサイトとしては危険な状態と言えるでしょう。今回のサンプルはあからさまですが、何らかの処理の途中にeval()が入ってしまうと危険性が増すので注意が必要となるのです。

Functionで代替

先ほどeval()が持つ注意するべき性質について解説しました。

これらの性質が理由で、eval()を使わずに代替することがよくあります。代替する場合はFunctionコンストラクタを使います。

var data = '{"name":"太郎","age":"30","tell":"090-1234-5678"}';
var result = (new Function("return" + data))();
console.log( result );

実行結果:

{name: "太郎", age: "30", tell: "090-1234-5678"}

Functionコンストラクタを使って代替する方法をお伝えしましたが、eval()を使わない方法だから安全という訳ではありません。eval()の代替方法については、こちらでも紹介されています。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval

まとめ

今回は、 文字列をJavaScriptコードとして解析・実行できる「eval()」について学習しました!

最後に、もう一度ポイントをおさらいしておきましょう!

  • eval()の引数に文字列を指定するだけで、JavaScriptコードを認識して実行することができる。
  • JSONデータをオブジェクト化するためにもeval()を利用することができる
  • eval()の注意点として「パフォーマンス」「乱雑性」「セキュリティリスク」がある

上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!

この記事を書いた人

フリーランスのIT系ライターを10年従事する兵庫県出身の40歳。侍ブログ編集部としては、これまで270記事以上を執筆。
30歳を過ぎてから独学でJavaScript, Node.js, Linuxを習得した経験を活かし、初心者が迷わない記事作成を意識しながらプログラミングの楽しさを知ってもらうために活動しています。趣味はキャンプと登山です。

目次