「便利だから」で済ませてはいけない。JavaScriptの「禁断の魔術」を安全なコードに書き換えよう
こんにちは。現場の最前線でセキュリティと向き合っているエンジニアです。
今日は、プログラミングを始めたばかりの方がつい使いがちな、でもセキュリティの観点からは「絶対にやってはいけないこと」の代表格、eval()関数のお話です。
「え、これを使うと簡単に動的な処理が書けて便利なのに…」そう思う気持ち、よく分かります。でも、これが「家に泥棒を招き入れるための合鍵」を渡しているのと同じだと言われたら、どう感じますか?
一歩ずつ、その危険性と正しい解決策を学んでいきましょう!
—
そもそも、eval()って何が悪いの?
eval()やsetTimeout(string)、setInterval(string)といった関数は、「文字列として渡されたものを、プログラムとしてそのまま実行する」という魔法のような機能を持っています。
泥棒の侵入経路に例えると…
想像してみてください。あなたは自分の家の玄関(プログラム)に、「玄関を通る時、ここに書かれた指示を何でも実行してね」という魔法のポストを設置しました。
本来なら、家族(正しいプログラム)だけが暗号を使って入るべきです。しかし、このポストは「通りすがりの泥棒が書いた指示」であっても、忠実に実行してしまいます。
もし誰かがここに、
"あなたの家の全財産を、泥棒の口座に転送する"
という文字列を書き込んだら? プログラムはそれを「命令」だと勘違いして、あなたの許可なく実行してしまうのです。これがインジェクション攻撃の入り口です。
—
具体的にどんな攻撃を受けるの?
例えば、ユーザーが入力した名前を画面に表示するプログラムがあったとします。
// 悪い例:ユーザーの入力をそのまま実行してしまう
const userInput = “alert(‘ハッキングしました!’)”; // 攻撃者が入力したとする
eval(userInput);
このコードを実行した瞬間、ブラウザ上で攻撃者が用意した命令が動いてしまいます。これは単なるポップアップですが、実際には「Cookie(ログイン情報)を盗んで外部に送信する」「悪意のあるサイトへ強制的にリダイレクトさせる」といった操作が、あなたのサイト上で自由に行われてしまうのです。
—
じゃあ、どうすればいいの?「安全な代替案」
コードを動的に実行したいシーンは確かにありますよね。でも、eval()を使わずに安全に書く方法は必ずあります!
1. JSONデータの取り扱い:JSON.parse()を使う
外部から受け取ったデータがJSON形式なら、絶対にeval()を使ってはいけません。代わりに、ブラウザに標準装備されている安全な解析機能を使います。
// 安全な例:JSON.parseを使う
const jsonString = ‘{“name”: “田中”, “age”: 25}’;
// JSON.parseは「文字列をただのデータとして解釈する」だけなので、コードは実行されません!
const data = JSON.parse(jsonString);
console.log(data.name); // 田中
2. 関数を動的に呼び出す:関数参照を使う
特定の条件で関数を切り替えたいときは、関数を「変数」として辞書のように管理しましょう。
// 安全な例:関数参照の辞書を作る
const actions = {
“greet”: () => console.log(“こんにちは!”),
“farewell”: () => console.log(“さようなら!”)
};
const command = “greet”; // ユーザーからの入力
// 文字列をキーにして、安全に登録された関数だけを呼び出す
if (actions[command]) {
actions[command]();
} else {
console.error(“そんなコマンドは存在しません!”);
}
—
最後に:防御の意識を「習慣」に
セキュリティ対策は、特別なことではありません。日頃のプログラミングで「外部からの入力は、すべて悪意があるかもしれない」と疑う癖をつけること。これが最強の防犯対策です。
eval()は使わない(これだけでリスクが激減します)setTimeoutやsetIntervalには文字列ではなく「関数オブジェクト」を渡すsetTimeout("alert('hi')", 1000);ではなく、setTimeout(() => alert('hi'), 1000);と書くのが正解です!
もし今、自分のコードにeval()や文字列を渡している場所があったら、今日のうちに書き換えてしまいましょう。
「便利さ」よりも「堅牢さ」を選ぶこと。それが、信頼されるエンジニアへの第一歩です。また次の記事で、一緒にセキュリティを学んでいきましょう!
コメント