サーバー側のEvalインジェクション

サーバー側のEvalインジェクション

説明

ユーザー入力を eval() に渡すと、攻撃者に意図しないコードを実行されるおそれがあります。eval() は文字列をJavaScriptとして解釈するため、細工した入力によってOSコマンドの実行、情報漏えい、サービス障害につながる可能性があります。

想定される影響

  • サーバー上での悪意のあるJavaScriptやシステムコマンドの実行
  • 内部データや環境変数の漏えい
  • 悪意のあるコードによるアプリケーションの停止や誤動作

対処方法

  • JSONデータを処理する場合は、eval() の代わりに JSON.parse() を使用してください。Function も文字列をコードとして実行するため、安全な代替手段ではありません。
  • ユーザー入力をコードとして実行しないでください。
  • 入力で処理を選択する場合は、事前に実装した処理の許可リストから選ばせてください。

例

変更前

javascript
app.get("/vuln", function (req, res) {
  const userCode = req.query.code;
  // ユーザー入力をコードとして実行
  eval(userCode);
  res.send("Done");
});

変更後

javascript
app.get("/safe", function (req, res) {
  const userJson = req.query.data;
  // 入力をJSONとしてのみ解析
  try {
    const parsed = JSON.parse(userJson);
    res.json(parsed);
  } catch (e) {
    res.status(400).send("Invalid input");
  }
});

解説:

  • 変更前: req.query.code をそのまま eval() で実行するため、悪意のあるJavaScriptによってサーバーの侵害や情報漏えいにつながるおそれがあります。
  • 変更後: JSON.parse() で入力をデータとして扱い、この経路でのコード実行をなくしています。用途に応じたデータ構造、サイズ、権限の検証は別途必要です。

参考資料