185.5. Jackson ObjectMapper
185.5.1. オブジェクトマッピングとは
					Jackson は、com.fasterxml.jackson.databind.ObjectMapper クラスを使用して、Java オブジェクトをシリアライズするメカニズムを提供します。たとえば、次のように ObjectMapper を使用して MyClass Java オブジェクトをシリアライズできます。
				
ObjectMapper objectMapper = new ObjectMapper();
MyClass myobject = new MyClass("foo", "bar");
objectMapper.writeValue(new File("myobject.json"), myobject);
ObjectMapper objectMapper = new ObjectMapper();
MyClass myobject = new MyClass("foo", "bar");
objectMapper.writeValue(new File("myobject.json"), myobject);
					オブジェクト myobject は JSON 形式にシリアル化され、ファイル myobject.json に書き込まれます (Jackson は XML および YAML 形式への変換もサポートしています)。
				
					ファイル myobject.json の JSON コンテンツをデシリアライズするには、次のように ObjectMapper を呼び出します。
				
ObjectMapper objectMapper = new ObjectMapper();
MyClass myobject = objectMapper.readValue(new File("myobject.json"), MyClass.class);
ObjectMapper objectMapper = new ObjectMapper();
MyClass myobject = objectMapper.readValue(new File("myobject.json"), MyClass.class);
					受信者は事前にクラスの型を知っている必要があり、型 MyClass.class を readValue () の 2 番目の引数として指定する必要があることに注意してください。
				
185.5.2. ポリモーフィックオブジェクトマッピングとは
					場合によっては、シリアル化されたオブジェクトの受信者がオブジェクトの型を事前に知ることができないことがあります。たとえば、これは多相オブジェクト配列の場合に当てはまります。抽象型 Shape とそのサブタイプ Triangle、Square (など) について考えてみましょう。
				
					次のように、形状の配列リスト (ListOfShape) をインスタンス化してシリアル化できます。
				
					しかし、今は受信側に問題があります。この型を readValue() の 2 番目の引数として指定することで、受信側に ListOfShape オブジェクトを期待するように指示できます。
				
MyClass myobject = objectMapper.readValue(serialized, ListOfShape.class); ObjectMapper objectMapper = new ObjectMapper();
MyClass myobject = objectMapper.readValue(serialized, ListOfShape.class);
ObjectMapper objectMapper = new ObjectMapper();
					ただし、リストの最初の要素が Triangle で 2 番目の要素が Square であることを受信者が知る方法はありません。この問題を回避するには、次のセクションで説明するように、ポリモーフィックオブジェクトマッピング を有効にする必要があります。
				
185.5.3. ポリモーフィックオブジェクトマッピングを有効にする方法
ポリモーフィックオブジェクトマッピングは、配列内のオブジェクトの型を識別する追加のメタデータをシリアル化された配列に提供することによって、抽象クラスの配列をシリアル化および逆シリアル化できるようにするメカニズムです。
ポリモーフィックオブジェクトマッピングには固有のセキュリティーリスクがあります。このメカニズムでは、インスタンス化するクラスを 送信者 が選択できるため、送信者による攻撃の基礎となる可能性があります。Red Hat の FasterXML Jackson ライブラリーのディストリビューションは、この脅威に対する追加レベルの保護を提供するホワイトリストメカニズムを特徴としています。この追加の保護レイヤーを取得するには、Red Hat の jackson-databind ライブラリーのディストリビューション (Fuse バージョン 7.7 以降で提供) を使用していることを確認する必要があります。詳細は、「ポリモーフィックデシリアライゼーションによるセキュリティーリスク」 を参照してください。
受信者が配列内のオブジェクトを逆シリアル化できるようにするには、シリアル化されたデータに型メタデータを提供する必要があります。デフォルトでは、Jackson はシリアル化されたオブジェクトのタイプメタデータをエンコードしないため、この機能を有効にするには追加のコードを記述する必要があります。
					ポリモーフィックオブジェクトマッピングを有効にするには、次の手順を実行します (例として ListOfShape を使用)。
				
- リストの要素となるクラス ( - Shapeのサブクラス) ごとに、次のように- @JsonTypeInfoでクラスにアノテーションを付けます。- @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY) public class Triangle extends Shape { ... }- @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY) public class Triangle extends Shape { ... }- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- Triangleクラスを JSON 形式にシリアル化すると、次の形式になります。- {"@class":"com.example.Triangle", "property1":"value1", "property2":"value2", ...}- {"@class":"com.example.Triangle", "property1":"value1", "property2":"value2", ...}- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- Triangle、- Square、およびその他の形状クラスを逆シリアル化ホワイトリストに追加して、これらのクラスの逆シリアル化を許可するようにレシーバーを設定する必要があります。ホワイトリストを設定するには、- jackson.deserialization.whitelist.packagesシステムプロパティーを、クラスおよびパッケージのコンマ区切りリストに設定します。たとえば、- Triangleクラスと- Squareクラスのデシリアライズを許可するには、システムプロパティーを以下のように設定します。- -Djackson.deserialization.whitelist.packages=com.example.Triangle,com.example.Square - -Djackson.deserialization.whitelist.packages=com.example.Triangle,com.example.Square- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - または、システムプロパティーを設定して、 - com.exampleパッケージ全体を許可することもできます。- -Djackson.deserialization.whitelist.packages=com.example - -Djackson.deserialization.whitelist.packages=com.example- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 注記- このホワイトリストメカニズムは、Red Hat の jackson-databind ライブラリーのディストリビューションでのみ使用できます。標準の jackson-databind ライブラリーは代わりにブラックリストメカニズムを使用します。このメカニズムは、潜在的に危険な新しいガジェットクラスが発見されるたびに更新する必要があります。 
185.5.4. ポリモーフィックデシリアライゼーションのデフォルトマッピング
					特定の Java クラス com.example.MyClass がホワイトリストに登録されていない場合でも、クラスのインスタンスをシリアライズすることは可能ですが、受信側では、インスタンスは汎用のデフォルトマッピングを使用してデシリアライズされます。
				
Jackson でポリモーフィックオブジェクトマッピングが有効になっている場合、オブジェクトをエンコードする別の方法がいくつかあります。
- @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY)の場合:- {"@class":"com.example.MyClass", "property1":"value1", "property2":"value2", ...}- {"@class":"com.example.MyClass", "property1":"value1", "property2":"value2", ...}- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - この場合、インスタンスはプロパティーを持つ - Objectに逆シリアル化されます。
- @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.WRAPPER_ARRAY)の場合:- ["com.example.MyClass", {"property1":"value1", "property2":"value2", ...}]- ["com.example.MyClass", {"property1":"value1", "property2":"value2", ...}]- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - この場合、インスタンスは 2 つのフィールドを含む JSON 配列に逆シリアル化されます。 - 
									値が com.example.MyClassのString
- 
									2 つ (またはそれ以上) のプロパティーを持つ Object
 
- 
									値が 
- @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.WRAPPER_OBJECT)の場合:- {"com.example.MyClass":{"property1":"value1", "property2":"value2", ...}}- {"com.example.MyClass":{"property1":"value1", "property2":"value2", ...}}- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - この場合、インスタンスは、1 つのフィールド - com.example.MyClassと、2 つ (またはそれ以上) のプロパティーを持つ- Objectとしての値を持つ JSON マップに逆シリアル化されます。
185.5.5. ポリモーフィックデシリアライゼーションによるセキュリティーリスク
					FasterXML jackson-databind ライブラリーを使用し、JSON コンテンツをデシリアライズして Java オブジェクトをインスタンス化するアプリケーションは、潜在的に リモートコード実行 攻撃に脆弱です。しかし、脆弱性は自動的に発生せず、適切な軽減策を講じれば回避することができます。
				
最低でも以下の前提条件をすべて満たさなければ攻撃を実行することはできません。
- jackson-databindの JSON コンテンツのデシリアライズに対し、ポリモーフィックな型の処理を有効にする必要があります。Jackson JSON でポリモーフィックな型の処理を有効にする方法は 2 つあります。- 
									@JsonTypeInfoおよび@JsonSubTypesアノテーションの組み合わせを使用します。
- 
									ObjectMapper.enableDefaultTyping()メソッドを呼び出します。この方法はポリモーフィックな型をグローバルで有効にするため、危険です。
 
- 
									
- Java クラスパスに 1 つ以上の ガジェットクラス があります。ガジェットクラスは、機密性の高い (潜在的に悪用可能な) 操作を、constructor または setter メソッド (デシリアライズ中に呼び出しできるメソッド) の実行による副次的な影響として定義します。
- 
							Java クラスパス内の 1 つ以上のガジェットクラスが、現在のバージョンの jackson-databindによってまだブラックリストに登録されていません。jackson-databind ライブラリーの標準ディストリビューションを使用している場合、Jackson JSON ライブラリーによって維持されるガジェットのブラックリストは、リモートコード実行の脆弱性に対する最後の防衛線です。
- 
							(jackson-databind ライブラリーの Red Hat ディストリビューションのみ) (jackson.deserialization.whitelist.packagesシステムプロパティーを設定することにより) レシーバーの逆シリアル化ホワイトリストにガジェットクラスの 1 つを明示的に追加しました。これを行う可能性は低いため、ホワイトリストメカニズムはデフォルトですべてのガジェットクラスに対して効果的な保護を提供します。