検索
連載

「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. 「このままゼロトラストへ進んでいいの?」と迷う企業やこれから入門する企業も必見、ゼロトラストの本質、始め方/進め方が分かる無料の電子書籍
  2. 米国/英国政府が勧告する25の脆弱性、活発に悪用されている9件のCVEとは、その対処法は? GreyNoise Intelligence調査
  3. ランサムウェア攻撃を受けた企業、約6割が「サプライチェーンのパートナー経由で影響を受けた」 OpenText調査
  4. セキュリティ担当者の54%が「脅威検知ツールのせいで仕事が増える」と回答、懸念の正体とは? Vectra AI調査
  5. 人命を盾にする医療機関へのランサムウェア攻撃、身代金の平均支払額や損失額は? 主な手口と有効な対策とは? Microsoftがレポート
  6. AIチャットを全社活用している竹中工務店は生成AIの「ブレーキにはならない」インシデント対策を何からどう進めたのか
  7. 長続きする高度セキュリティ人材育成の秘訣を「第19回情報危機管理コンテスト」から探る
  8. OpenAIの生成AIを悪用していた脅威アクターとは? OpenAIが脅威レポートの最新版を公開
  9. ゼロトラストの理想と現実を立命館大学 上原教授が語る――本当に運用できるか? 最後は“人”を信用できるかどうか
  10. 「PC操作が不能になる手口」が増加中 IPAが推奨される対処法を紹介
ページトップに戻る