検索
連載

「JSON文字列へのインジェクション」と「パラメータの追加」NoSQLを使うなら知っておきたいセキュリティの話(2)(1/2 ページ)

MongoDBを用いたWebアプリケーションで生じる可能性がある4種類の脆弱性のうち、今回は「JSON文字列へのインジェクション」と「パラメータの追加」のメカニズムと対策について説明します。

Share
Tweet
LINE
Hatena

 前回の「『演算子のインジェクション』と『SSJI』」では、MongoDBを用いたWebアプリケーションで生じうる脆弱性のうち「演算子のインジェクション」と「SSJI」について、攻撃の実例と対策について解説しました。今回はさらに、「JSON文字列へのインジェクション」と「パラメータの追加」について説明します。

JSON文字列へのインジェクション

 これまで見てきたように、PHP言語においては連想配列を指定してデータの登録処理や検索処理を実行できます。しかし型の扱いが厳格な言語では、もう少し手間の掛かるプログラミングが必要になることがあります。ここではそのような例として、Javaで書かれたデータ登録プログラムを取り上げ、その脆弱性について説明します。

 脆弱なアプリケーションの説明をする前に、Java言語においてMongoDBにデータを登録する一般的なプログラム(脆弱ではないプログラム)を紹介します。対比のために、同じ処理を行うPHPとJavaのプログラムを記述しています。

// PHP版
// データを登録
$member = array('type' => 'member',
                'name' => 'MBSD',
                'interests' => array('music', 'travel');
$db->members->insert($member);
PHPのプログラム
// Java版
// interests配列を作成
ArrayList<String> interests = new ArrayList<String>();
interests.add("music");
interests.add("travel");
// 登録するデータの全体を作成
BasicDBObject member = new BasicDBObject("type", "member")
    .append("name", "MBSD")
    .append("interests", interests);
// データを登録
db.getCollection("members").insert(member);
Javaのプログラム

 前者のPHPのプログラムと比べると、後者のJavaのプログラムがデータ構造に依存した煩雑な処理になっていることは否めません。そのためだと思われますが、ネット上には下記のように、JSON文字列を生成してクエリを行うJavaのプログラムも紹介されています。

// JSON文字列をDBObjectに変換する
String json = "{'type':'member', 'name':'MBSD', 'interests':['music','travel']}";
DBObject member = (DBObject) JSON.parse(json);
// データを登録
db.getCollection("members").insert(member);

 上記プログラムのJSONクラスは、MongoDBに含まれているクラス(com.mongodb.util.JSON)です。このクラスは文字列の括り文字として「'」も受け入れます。説明を簡単にするため、以降のプログラムでは「'」を使用します。

脆弱なアプリケーションの例

 JSON文字列が固定ならば、上記のようなプログラムに問題はありません。しかし、下記のプログラムのように、入力パラメータから取得した値をそのまま埋め込んでJSONを生成してしまうと、その限りではなくなります。

// リクエストパラメータから各要素の値を取得
String name = request.getParameter("name");
String interest1 = request.getParameter("interest1");
String interest2 = request.getParameter("interest2");
// JSON文字列を生成し、DBObjectに変換する
String json = "{'type':'member', 'name':'%1$s', 'interests':['%2$s','%3$s']}";
json = String.format(json, name, interest1, interest2);
DBObject member = (DBObject) JSON.parse(json);
// データを登録
db.getCollection("members").insert(member);

 上記プログラムの正常なパラメータ例を下記に示します。

正常パラメータ例: name=MBSD&interest1=music&interest2=travel


 JSON文字列内でtype(会員種別)は、'member'の固定値となっていますが、これを回避してtypeが'admin'のユーザーを登録することが攻撃の目標です。

攻撃例

 攻撃者はJSON文字列を生成している個所を突いて攻撃を行います。具体的には、下記のように操作したパラメータを送信します。

操作パラメータ例: name=MBSD', 'type':'admin&interest1=music&interest2=travel


 すると、プログラムにより生成されるJSON文字列は下記となります。

{'type':'member', 'name':'MBSD', 'type':'admin', 'interests':['music','travel']}


 JSON文字列には、ハードコードされている「先頭のtype」と攻撃者が挿入した「後方のtype」の2つが存在しますが、実際にMongoDBに登録される値は下記のようになります。データベースには、後方の値によってtypeが'admin'に上書きされたデータが登録されてしまったことが分かります。

{ "_id" : ObjectId("512dd4fae4b0f17388cb3983"), "type" : "admin", "name" : "MBSD", "interests" : [ "music", "travel" ] }


対策

 対策の選択肢は2つあります。1つは、先に挙げた脆弱性のないJava版プログラムのように、JSON文字列を経由しない方法でクエリを生成する方法です。もう1つは、JSON文字列を生成する際に、文字列についてはエスケープ、数値/真偽値については型変換を行う方法です。文字列のエスケープについては、RFC4627に規定された処理を自作するか、既存のJSON処理用のJavaのライブラリを使用します。

Copyright © ITmedia, Inc. All Rights Reserved.

       | 次のページへ

Security & Trust 記事ランキング

  1. 1年前と比べて1Tbpsを超えるDDoS攻撃が1885%増加、今すぐできる対策は? Cloudflare
  2. 米ホワイトハウス、“懸念国”への半導体輸出、AI規制を発表 日本含む18カ国は規制対象外
  3. 終わらせましょう。複雑過ぎるKubernetes/クラウドネイティブが生む心理的安全性の低下を――無料でクラウドセキュリティの勘所が分かる130ページの電子書籍
  4. 「SMSは認証に使わないで」 米CISA、モバイル通信を保護する8つのベストプラクティスを公開
  5. 「Appleの暗号化アルゴリズム」を盗用し、2カ月以上検出されなかったステルス型マルウェアの正体とは
  6. Google Cloud、2025年のサイバーセキュリティ予測を発表 AIがサイバー攻撃にもたらす影響とは?
  7. 経営層の約7割が「セキュリティ対策は十分」一方で6割以上がインシデントを経験、1位の要因は?
  8. “ゼロトラスト”とトラスト(信頼性)ゼロを分かつものとは――情報セキュリティ啓発アニメ「こうしす!」監督が中小企業目線で語る
  9. 2025年に押さえるべきセキュリティの重要論点をガートナーが発表 新しいリスク、脅威、環境の変化、法規制などの動きを把握する指標に使える
  10. よく聞く「複雑化するサイバー攻撃」は具体的にどう複雑なのか? 一例を医療系企業のランサム事例とともに解説
ページトップに戻る