WebVulnerabilities

プロトタイプ汚染攻撃について

概要

プロトタイプ汚染攻撃は、特にJavaScript(Node.js)に関連する脆弱性です。この攻撃は、JavaScriptオブジェクトのプロトタイプ(prototype)を操作することで、他のオブジェクトに予期しないプロパティを追加したり、既存のプロパティを上書きしたりする攻撃手法です。プロトタイプ汚染が成功すると、アプリケーションの動作が不正に変更される可能性があり、重大なセキュリティ問題を引き起こすことがあります。

脆弱性を持つコードの例と攻撃手法

Node.js

脆弱なコード:

const _ = require('lodash');

let userInput = {
  username: "user",
  admin: false
};

// 深いマージを行うために使用されるコード
_.merge(userInput, JSON.parse('{"__proto__": {"admin": true}}'));

console.log(userInput.admin); // 出力: true

攻撃手法: userInputオブジェクトのプロトタイプにadminプロパティを追加することで、userInput.adminの値が意図せずtrueに設定されます。これにより、通常は権限がないユーザーが管理者として扱われる可能性があります。

言語別の差異


防止策

  1. 信頼できない入力をそのままオブジェクトに割り当てない: ユーザーからの入力がプロトタイプにアクセスできないように、信頼できないデータを直接オブジェクトに割り当てないようにします。

    function safeMerge(target, source) {
      for (let key in source) {
        if (source.hasOwnProperty(key)) {
          target[key] = source[key];
        }
      }
    }
    

    この例では、hasOwnPropertyを使って、オブジェクト自身のプロパティのみを対象にしています。

  2. オブジェクトをクリーンにする: プロトタイプ汚染の影響を受けないために、オブジェクト作成時にObject.create(null)を使用し、プロトタイプを持たないオブジェクトを作成します。

    let obj = Object.create(null);
    
  3. ライブラリのアップデートとバージョン管理: lodashやその他のライブラリでプロトタイプ汚染に関連する脆弱性が報告された場合、ライブラリを最新の安全なバージョンにアップデートすることが重要です。

  4. セキュリティに配慮したライブラリの使用: 可能であれば、信頼性の高い、セキュリティに配慮したライブラリやフレームワークを使用することで、プロトタイプ汚染のリスクを低減します。


まとめ

プロトタイプ汚染攻撃は、特にJavaScript(Node.js)のオブジェクト操作に関連する脆弱性です。信頼できない入力を直接オブジェクトに割り当てない、プロトタイプが汚染されないようにオブジェクトを適切に作成するなどの対策が有効です。PHP、Python、Java、Perlではこのような攻撃は原理的に発生しませんが、オブジェクトやクラスに対する不正な操作には注意が必要です。