動的なrequireによるEvalインジェクション

動的なrequireによるEvalインジェクション

説明

require() に渡すモジュール名やファイルパスをユーザー入力で指定できると、意図しないJavaScriptや悪意のあるモジュールを読み込んで実行させられるおそれがあります。対象になるのは、サーバーがアクセスして読み込めるモジュールやファイルです。

想定される影響

  • サーバー上での悪意のあるコードの実行
  • システムやソースコード内の機密情報へのアクセス
  • 想定外のモジュールの読み込みによるサービス障害

対処方法

  • require には固定のモジュール名や信頼できる値だけを渡してください。
  • モジュールやファイルを動的に選ぶ必要がある場合は、許可リストで選択肢を制限してください。
  • 入力とパスを検証し、選んだモジュールを通じて外部に提供する機能も必要な範囲に制限してください。

例

変更前

javascript
function loadModule(moduleName) {
  // ユーザー入力をそのままrequireに渡す
  return require(moduleName);
}

変更後

javascript
function loadModule(moduleName) {
  // 許可リストにあるモジュール名だけを使用
  const allowedModules = ['fs', 'path'];
  if (!allowedModules.includes(moduleName)) {
    throw new Error('허용되지 않은 모듈입니다.');
  }
  return require(moduleName);
}

解説:

  • 変更前: ユーザーが指定した moduleName をそのまま require に渡すため、意図しないモジュールを読み込む可能性があります。
  • 変更後: モジュール名を fs と path に限定し、他のモジュールやファイルを選べないようにしています。これらのモジュールを通じて行うファイル操作の権限まで制限するものではありません。

参考資料