【入門編】JavaScriptのeval()およびsetTimeout()への文字列渡しによるコード実行リスク – アプリケーションセキュリティ & 安全な開発防御ガイド

その「魔法の箱」、実は泥棒の入り口かもしれません。JavaScriptの危険な関数を封印しよう

こんにちは。セキュリティの世界へようこそ。今日は、プログラミングを始めたばかりの方がつい使いがちな「魔法の関数」のお話です。

皆さんは、家の玄関に「どんな人間でも一言挨拶すれば通してあげる」という自動ドアを設置しますか? もちろんしませんよね。でも、実は多くの初心者エンジニアが、自分の書いたプログラムの中で、これと全く同じことをしてしまっているんです。

今日は、JavaScriptのeval()やsetTimeout()に潜む「インジェクション攻撃」の罠と、そのスマートな回避術について、一緒に紐解いていきましょう。

—

1. 「魔法の関数」の正体は、招かれざる客の入り口

JavaScriptには、文字列をプログラムの命令として実行してしまう、非常に強力な関数があります。代表的なのが eval() です。

例えば、こんなコードを書いたとします。

// ユーザーからの入力値をそのまま計算してしまう例
let userInput = “alert(‘ハッキング成功!’)”; // 本来は数字が入るはずの場所
eval(userInput); // 文字列が命令として実行されてしまう!

この eval() は、渡された文字列を「これはプログラムの命令だ!」と信じ込んで即座に実行します。もし、入力欄に悪意ある第三者が「サイトを改ざんするコード」や「個人情報を盗むコード」を入力したらどうなるでしょうか?

あなたのプログラムは、「泥棒が『私は家主です』と書いたメモを差し出したら、何の疑いもなく玄関を開けてしまう」のと同じ状態になっています。これが、インジェクション攻撃の入り口です。

2. 意外な伏兵:setTimeout() の文字列渡し

実は、setTimeout() も使い方を間違えると危ないんです。

// これは「ダメな例」です
setTimeout(“console.log(‘実行されました’)”, 1000);

引数に文字列を渡すと、内部で eval() と同じ処理が走ります。便利に見えますが、これではプログラムの健全性が保てません。現代のWeb開発では、文字列を渡すのではなく、「関数そのもの」を渡すのが鉄則です。

// これが「正しい例」です
setTimeout(() => {
console.log(‘実行されました’);
}, 1000);

これなら、もし誰かが意図しない文字列を入れようとしても、プログラムが「それは関数じゃないから実行できないよ」と弾いてくれます。

3. 「何でも屋」を卒業して、専用ツールを使おう

「動的なデータを受け取って、それをオブジェクトとして扱いたい」という場面はよくありますよね。そんな時、eval() で無理やり変換するのは非常に危険です。

代わりに、JSON専用の安全な処理装置である JSON.parse() を使いましょう。

// 外部から届いたデータ
let data = ‘{“name”: “セキュリティ太郎”, “role”: “admin”}’;

// 安全な変換処理
try {
let user = JSON.parse(data);
console.log(user.name); // ちゃんと中身を取り出せます
} catch (e) {
console.error(“不正なデータ形式です!”);
}

JSON.parse() は、あくまで「データを読み込む」ことしかできません。命令を実行する権限はないので、泥棒がどんなコードを仕込んでも、ただの「文字の羅列」として処理されます。「玄関を開けるのではなく、郵便受けから中身を確認する」という、安全な仕組みに切り替えるイメージです。

4. 最後の守護神:CSP(コンテンツセキュリティポリシー)

ここまで対策しても、万が一のミスはあるかもしれません。そこで、ブラウザ側で「怪しい命令は絶対に実行させない!」という強力なバリアを張るのが CSP です。

サーバーからWebブラウザに対して、「うちのサイトでは eval() やインラインスクリプトの実行は一切禁止!」と宣言する設定です。

Webサーバー(NginxやApacheなど)の応答ヘッダーに、以下のような設定を追加してみてください。

HTTP応答ヘッダー例
Content-Security-Policy: default-src ‘self’; script-src ‘self’;

  • default-src 'self':自分のドメイン以外からの読み込みを禁止する。
  • script-src 'self':信頼できない外部スクリプトや、eval() のような危険な実行をブロックする。

これだけで、たとえプログラムに隙があったとしても、ブラウザが「その命令は危険だから実行しません!」と門前払いしてくれるようになります。

—

最後に:セキュリティは「疑うこと」から始まる

セキュリティ対策とは、何か特別な魔法をかけることではなく、「自分の書いたコードに、悪意ある誰かが入り込む余地はないか?」と、常に玄関の鍵を確認する習慣のことです。

eval() を使いたくなったら、一度立ち止まって考えてみてください。「本当に文字列を実行する必要があるかな?」「もっと安全な別の関数はないかな?」と。

その小さな疑問が、あなたのサービスと、大切なユーザーを守る一番の盾になります。一歩ずつ、安全な開発者への道を歩んでいきましょうね!

コメント

タイトルとURLをコピーしました