12 Java API for XML Processing (JAXP)セキュリティ・ガイド
JDKおよびJava XML APIは、アプリケーションがXML関連の攻撃によって悪用されないようにするのに役立つ様々な手段とツールで何年にもわたり改善されてきました。このガイドでは、Java API for XML Processing (JAXP)のセキュア処理機能を使用してアプリケーションおよびシステムを保護する方法を示します。
XML処理中の潜在的な攻撃
XML処理は、アプリケーションを一定の脆弱性に晒すことがあります。最も顕著で有名な攻撃は、XML外部エンティティ(XXE)インジェクション攻撃と指数関数的エンティティ展開攻撃で、XML爆弾やBillion laughs攻撃とも呼ばれます。これらの攻撃は、そのサービスを拒否することでシステムの重大な破損を引き起こしたり、さらに悪いことに機密データの喪失につながったりすることがあります。
アプリケーションの要件およびオペレーティング環境を評価して、潜在的な脅威のレベル(たとえば、信頼できないXMLソースにアプリケーションが公開されているかどうか、またはどの程度公開されているか)を評価する必要があります。
XML外部エンティティ・インジェクション攻撃
XML、XMLスキーマおよびXSLT標準では、外部リソースを参照するシステム識別子を通じてXMLドキュメントに外部コンテンツを埋め込むことができる構造をいくつか定義します。一般に、XMLプロセッサは、これらの外部リソースのほぼすべてを解決および取得します。外部リソースの挿入をサポートするコンストラクトのリストは、「XML、スキーマおよびXSLT標準でサポートされる外部リソース」を参照してください。また、一部のコンストラクトでは、外部関数を通じてアプリケーションを実行できます。XML外部エンティティ(XXE)インジェクション攻撃は、解決、取得または実行できる外部リソースの制限によって保護されていないXMLプロセッサを悪用します。これにより、パスワードなどの機密データが開示されたり、コードを任意に実行できるようになったりすることがあります。
XML、スキーマおよびXSLT標準でサポートされている外部リソース
XML、スキーマおよびXSLT標準では、外部リソースを必要とする次のコンストラクトがサポートされています。JDK XMLプロセッサのデフォルトの動作では、接続を作成し、指定された外部リソースをフェッチします。
-
外部DTD: 外部ドキュメント・タイプ定義(DTD)を参照します。たとえば:
<!DOCTYPE root_element SYSTEM "url">
-
外部エンティティ参照: 外部データを参照します。次に構文を示します。
<!ENTITY name SYSTEM "url">
-
一般エンティティ参照。たとえば:
<?xml version="1.0" standalone="no" ?> <!DOCTYPE doc [<!ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <a> <b>&otherFile;</b> </a> </doc>
-
外部パラメータ・エンティティ: 次に構文を示します。
<!ENTITY % name SYSTEM uri>
次に、例を示します。
<?xml version="1.0" standalone="no"?> <!DOCTYPE doc [ <!ENTITY % ent1 SYSTEM "http://www.example.com/student.dtd"> %ent1; ]>
- XInclude: XMLドキュメントに外部情報セットを含めます。たとえば:
<Book xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href=toc.xml"/> <xi:include href=part1.xml"/> <xi:include href=part2.xml"/> <xi:include href=index.xml"/> </Book>
-
schemaLocation
属性とimport
要素およびinclude
要素を使用してXMLスキーマ・コンポーネントを参照します。たとえば:<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:include schemaLocation="http://www.example.com/schema/schema1.xsd"/> <!-- ... --> </xs:schema>
- importまたはinclude要素を使用したスタイル・シートの結合。次に構文を示します。
<xsl:include href="include.xsl"/>
xml-stylesheet
処理命令: スタイルシートをXMLドキュメントに含めるために使用します。たとえば:<?xml-stylesheet href="include.xsl" type="text/xsl"?>
- XSLT
document()
関数: 外部XMLドキュメントのノードにアクセスするために使用します。たとえば:<xsl:variable name="dummy" select="document('DocumentFunc2.xml')"/>
指数関数的エンティティ展開攻撃
XML爆弾またはBillion laughs攻撃とも呼ばれる指数関数的エンティティ展開攻撃は、XMLパーサーを含むサービス拒否攻撃です。基本的な悪用は、各レイヤーが次のレイヤーのいくつかのエンティティを参照する、ネストされたエンティティの複数のレイヤーの使用です。次に、深くネストされたエンティティ参照を含むSOAPドキュメントのサンプルを示します。
<?xml version="1.0" encoding ="UTF-8"?>
<!DOCTYPE bbb[
<!ENTITY x100 "bbb">
<!ENTITY x99 "&x100;&x100;">
<!ENTITY x98 "&x99;&x99;">
...
<!ENTITY x2 "&x3;&x3;">
<!ENTITY x1 "&x2;&x2;">
]>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=...>
<SOAP-ENV:Body>
<ns1:aaa xmlns:ns1="urn:aaa" SOAP-ENV:encodingStyle="...">
<foobar xsi:type="xsd:string">&x1;</foobar>
</ns1:aaa>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XMLパーサーは、このようなドキュメントを検出すると、参照を展開してエンティティ宣言を解決しようとします。参照はネストされているため、展開は、それぞれが参照するエンティティ数によって指数関数的になります。このようなプロセスによって、XMLパーサーが100%のCPU時間と大量のメモリーを消費し、最終的にシステムのメモリーが不足する可能性があります。
セキュア処理機能(FSP)
javax.xml.XMLConstants.FEATURE_SECURE_PROCESSINGとして定義されているセキュア処理機能(FSP)は、XML処理を保護するための中心的なメカニズムです。XMLをセキュアに試行して処理するようXMLプロセッサ(パーサー、バリデータ、トランスフォーマなど)に指示します。
デフォルトでは、JDKはDOMおよびSAXパーサーやXMLスキーマ・バリデータのFSPをオンにします。これらは、プロセッサに対して多数の処理制限を設定します。反対に、JDKではデフォルトでトランスフォーマとXPathのFSPがオフになります。これにより、XSLTおよびXPathの拡張関数が使用可能になります。
ファクトリでsetFeatureメソッドを呼び出し、XMLConstants.FEATURE_SECURE_PROCESSINGをtrue
またはfalse
のいずれかに設定して、FSPをオンおよびオフにします。たとえば、次のコード・スニペットは、XMLConstants.FEATURE_SECURE_PROCESSINGをtrue
に設定することにより、ファクトリspf
によって作成されるSAXパーサーのFSPをオンにします。
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
FSPはファクトリを通じてオンまたはオフにすることができますが、Javaセキュリティ・マネージャが存在する場合は常にオンになり、オフにはできません。このため、Java XMLプロセッサは、Javaセキュリティ・マネージャが存在する場合に制限と制約を適用します。ただし、アプリケーションの具体的なニーズに応じて、個々のプロパティを調整できます。JAXPプロパティには、次の2種類があります。
- 処理の制限: XML処理からの過剰なメモリー消費の防止に役立ちます。
- 外部アクセスの制限: 外部リソースのフェッチを制御します。
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。次の項では、これらの2種類のJAXPプロパティについて説明します。
処理制限用のJAXPプロパティ
XML処理は、メモリー集中型の操作である場合があります。信頼できないソースからのXML、XSDおよびXSLを受け入れるアプリケーションでは特に、処理制限用のJAXPプロパティを使用して、過剰なメモリー消費を回避するステップをとる必要があります。
アプリケーションの要件およびオペレーティング環境を評価して、システム構成の許容可能な処理制限を判断し、それに応じてこれらの制限を設定します。たとえば、サイズ関連の制限を使用して、不適切なXMLソースによる大量のメモリー消費を防止します。アプリケーションでメモリー消費を許容レベルに制御できるようにするには、jdk.xml.entityExpansionLimit
プロパティを使用します。
JDK XMLパーサーは、デフォルトで処理制限を監視します。DOMおよびSAXパーサーでは、セキュア処理機能(FSP)がデフォルトでオンになっているため、制限がオンになります。また、StAXパーサーは、FSPをサポートしていなくても、デフォルトで処理制限を遵守します。
JDK XMLプロセッサを使用すると、処理制限を3つの方法で個別に調整できます。
- 標準のXML APIを使用
- システム・プロパティを使用
jaxp.properties
ファイル内
「JAXPプロパティの使用」および「スコープと順序」を参照してください。
次の表に、JDKでサポートされる処理制限用のJAXPプロパティを示します。これらの各処理制限の値は正の整数です。0以下の値は、制限がないことを示します。値が整数でない場合は、NumericFormatException
がスローされます。
詳細は、java.xmlモジュールのサマリーにある実装固有のプロパティの表を参照してください。
表12-1 JAXP処理制限のプロパティ
プロパティ名およびシステム・プロパティ | 説明 | デフォルト値 |
---|---|---|
jdk.xml.elementAttributeLimit |
1つの要素で使用できる属性の数を制限します。 | 10000 |
jdk.xml.entityExpansionLimit |
エンティティの展開数を制限します。 | 64000 |
jdk.xml.entityReplacementLimit |
すべてのエンティティ参照のノードの合計数を制限します。 | 3000000 |
jdk.xml.maxElementDepth |
要素の最大の深さを制限します。 | 0 |
jdk.xml.maxGeneralEntitySizeLimit |
すべての一般エンティティの最大サイズを制限します。 | 0 |
jdk.xml.maxOccurLimit |
"unbounded"以外の値を持つmaxOccurs 属性を含むW3C XMLスキーマの文法の構築時に作成できるコンテンツ・モデル・ノードの数を制限します。
|
5000 |
jdk.xml.maxParameterEntitySizeLimit |
複数のパラメータ・エンティティのネストの結果を含む、パラメータ・エンティティの最大サイズを制限します。 | 1000000 |
jdk.xml.maxXMLNameLimit |
要素名、属性名、名前空間の接頭辞やURIなど、XML名の最大サイズを制限します。 | 1000 |
jdk.xml.totalEntitySizeLimit |
一般エンティティとパラメータ・エンティティを含むすべてのエンティティの合計サイズを制限します。サイズはすべてのエンティティの集約として計算されます。 | 5x10^7 |
jdk.xml.xpathExprGrpLimit |
XPath式に含めることができるグループの数を制限します。 | 10 |
jdk.xml.xpathExprOpLimit |
XPath式に含めることができる演算子の数を制限します。 | 100 |
jdk.xml.xpathTotalOpLimit |
XSLスタイルシートのXPath演算子の総数を制限します。 | 100000 |
外部アクセス制限用のJAXPプロパティ
外部アクセス制限用のJAXPプロパティを対応するシステム・プロパティとともに使用すると、外部接続を規制できます。
外部アクセス制限を使用すると、許可できるまたは許可できない外部接続のタイプを指定できます。プロパティ値は、プロトコルのリストです。JAXPプロセッサは、プロトコルをリスト内のプロトコルと照合することによって、特定の外部接続が許可されているかどうかをチェックします。プロセッサは、リスト上にある場合は接続を確立しようとし、そうでない場合は拒否しようとします。これらのJAXPプロパティをカスタム・リゾルバおよびカタログAPIとともに使用して(「リゾルバおよびカタログの使用」を参照)、ローカル・リソースを拒否および解決することにより、外部接続のリスクを軽減します。
ノート:
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
などのAPIを通じてセキュア処理機能(FSP)を明示的にオンにし、すべての外部接続を無効にします。
外部アクセス制限JAXPプロパティは、javax.xml.XMLConstantsで次のように定義されます。
- javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
- javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
- javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET
表12-2 ACCESS_EXTERNAL_DTD
属性 | 説明 |
---|---|
名前 | http://javax.xml.XMLConstants/property/accessExternalDTD |
定義 | 外部DTDおよび外部エンティティ参照へのアクセスを指定されたプロトコルに制限します。 |
値 | 「外部アクセス制限のJAXPプロパティの値」を参照してください |
デフォルト値 | all。すべてのプロトコルへの接続が許可されます |
システム・プロパティ | javax.xml.accessExternalDTD |
表12-3 ACCESS_EXTERNAL_SCHEMA
属性 | 説明 |
---|---|
名前 | http://javax.xml.XMLConstants/property/accessExternalSchema |
定義 | schemaLocation 属性、import 要素およびinclude 要素によって設定された外部参照へのアクセスを指定されたプロトコルに制限します。
|
値 | 「外部アクセス制限のJAXPプロパティの値」を参照してください |
デフォルト値 | all。すべてのプロトコルへの接続が許可されます。 |
システム・プロパティ | javax.xml.accessExternalSchema |
表12-4 ACCESS_EXTERNAL_STYLESHEET
属性 | 説明 |
---|---|
名前 | http://javax.xml.XMLConstants/property/accessExternalStylesheet |
定義 | stylesheet 処理命令、document 関数、import およびinclude 要素によって設定された外部参照へのアクセスを指定されたプロトコルに制限します。
|
値 | 「外部アクセス制限のJAXPプロパティの値」を参照してください |
デフォルト値 | all。すべてのプロトコルへの接続が許可されます。 |
システム・プロパティ | javax.xml.accessExternalStylesheet |
外部アクセス制限のJAXPプロパティの値
外部アクセス制限用のすべてのJAXPプロパティが同じ形式の値を持ちます。
-
値: カンマで区切られたプロトコルのリスト。プロトコルは、URIのスキーム部分であり、JARプロトコルの場合は
jar
に、コロンで区切られたスキーム部分が付け加えられたものになります。スキームは次のように定義されます。scheme = alpha *( alpha | digit | "+" | "-" | "." )
ここで、
JARプロトコルは、alpha
=a-z
およびA-Z
です。jar[:scheme]
として定義されますプロトコルでは大文字と小文字が区別されません。値に含まれる、Character.isSpaceCharで定義された空白はすべて無視されます。プロトコルの例として、
file
、http
およびjar:file
があります。 -
デフォルト値: デフォルト値は実装固有です。JDKの場合、デフォルト値は
all
で、すべてのプロトコルに対するアクセス権を付与します。 -
すべてのアクセスの許可: キーワード
all
は、すべてのプロトコルに対するアクセス権を付与します。たとえば、JAXP構成ファイルでjavax.xml.accessExternalDTD=all
を指定すると、システムは以前のように外部DTDおよびエンティティ参照へのアクセスに対する制限なしで機能できます。 -
アクセスの拒否: 空の文字列(
""
)は、どのプロトコルに対してもアクセス権が付与されていないことを意味します。たとえば、JAXP構成ファイルにjavax.xml.accessExternalDTD=""
を指定すると、JAXPプロセッサは外部接続を拒否します。
スコープと順序
セキュア処理機能の設定のスコープ
XMLプロセッサ(DOM、SAX、スキーマ検証、XSLT、XPathなど)には、セキュア処理機能(FSP)が必要です。
FSPをオンにすると、デフォルトの処理制限(「処理制限用のJAXPプロパティ」を参照)が適用されます。FSPをオフにしても制限は変更されません。
API (たとえばfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
)を使用してFSPを"明示的"にオンにすると、外部アクセス制限(「外部アクセス制限用のJAXPプロパティ」を参照)は空の文字列に設定されます。これは、どのプロトコルに対してもアクセス権が付与されないことを意味します。FSPはDOM、SAXおよびスキーマ検証に対してデフォルトでオンになりますが、"明示的"にオンになっているものとしては扱われません。したがって、外部アクセス制限のデフォルト値はall
で、これはすべてのプロトコルに対してアクセス権が付与されることを意味します。
Javaセキュリティ・マネージャが存在する場合、FSPはオンになり、オフにはできません。
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。JAXPプロパティの設定のスコープおよび順序
一般に、より小さいスコープに設定されたJAXPプロパティは、より大きいスコープのJAXPプロパティより優先されます。
- JAXPファクトリまたはプロセッサを介して指定されるJAXPプロパティは、システム・プロパティ、
jaxp.properties
ファイルおよびFSPよりも優先されます。 - システム・プロパティが設定されている場合は、JDKの1回の起動のみに影響し、デフォルトで設定されているか、
jaxp.properties
ファイルで設定されているか、FSPによって設定されている処理制限および外部アクセス制限の値をオーバーライドします。 jaxp.properties
ファイルで指定されたプロパティはJDK全体に影響し、デフォルトで設定されているかFSPで設定されている処理制限および外部アクセス制限の値をオーバーライドします。
外部アクセス制限の設定のスコープ
外部アクセス制限は、次のような状況で制限しようとする関連コンストラクトには影響しません。
-
リゾルバがあり、リゾルバによって返されたソースがnullではない場合: これは、SAXおよびDOMパーサーで設定できるエンティティ・リゾルバ、StAXパーサー上のXMLリゾルバ、SchemaFactory上のLSResourceResolver、ValidatorまたはValidatorHandler、あるいはトランスフォーマ上のURIResolverに適用されます。
-
SchemaFactoryからnewSchemaメソッドを呼び出してスキーマが明示的に作成された場合。
-
外部リソースが不要な場合: たとえば、JDKでは次の機能とプロパティがサポートされており、外部DTDをロードしないようにプロセッサに指示したり外部エンティティを解決するために使用できます。
http://apache.org/xml/features/disallow-doctype-decl true http://apache.org/xml/features/nonvalidating/load-external-dtd false http://xml.org/sax/features/external-general-entities false http://xml.org/sax/features/external-parameter-entities false
セキュリティ・マネージャとの関係
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。SecurityManagerの有無に関係なく、JAXPプロパティは接続が試行される前に最初にチェックされます。つまり、SecurityManagerによってアクセス権を付与されている場合でも、接続をブロックできます。たとえば、JAXPプロパティがHTTPプロトコルを許可しないように設定されている場合、アプリケーションにSocketPermissionがあっても、実際には接続試行がブロックされます。
接続を制限する目的で、SecurityManagerは下位レベルと見なすことができます。JAXPプロパティが評価された後、アクセス権がチェックされます。たとえば、アプリケーションにSocketPermissionがない場合は、JAXPプロパティがHTTP接続を許可するように設定されていても、SecurityExceptionがスローされます。
SecurityManagerが存在する場合、セキュア処理機能(FSP)はtrueに設定されます。この動作によって外部アクセス制限がオンになることはありません。
処理制限をいつ使用するか
適用する処理制限および使用する値を決定する場合は、システム・レベルで、アプリケーションで使用可能なメモリー量、および信頼できないソースからのXML、XSDまたはXSLソースが受け入れられて処理されるかどうかを検討します。アプリケーション・レベルでは、DTDなどの特定のコンストラクトを使用するかどうかを検討します。
メモリー設定および制限
XML処理では、メモリーが大量に消費される可能性があります。消費できるメモリー量は、特定の環境におけるアプリケーションの要件によって異なります。不適切なXMLデータの処理によってメモリーが過剰に消費されるのを防ぐ必要があります。
通常、デフォルトの制限は、メモリー使用量がPCなどの小規模なハードウェア・システムに対して許容される量であるほとんどのアプリケーションで正当なXML入力が可能になるように設定されます。不正な入力が大量のメモリーを消費する前にそれを捕捉できるように、制限を可能な最小値に設定することをお薦めします。
制限は相関していますが、完全に冗長ではありません。すべての制限に適切な値を設定する必要があります。通常、制限はデフォルトより大幅に小さい値に設定する必要があります。
たとえば、ENTITY_EXPANSION_LIMIT
およびGENERAL_ENTITY_SIZE_LIMIT
を設定して、過剰なエンティティ参照を防ぐことができます。ただし、展開とエンティティ・サイズの正確な組合せが不明な場合は、TOTAL_ENTITY_SIZE_LIMIT
が全体的な制御として機能できます。同様に、TOTAL_ENTITY_SIZE_LIMIT
は置換テキストの合計サイズを制御しますが、テキストがXMLの非常に大きいチャンクである場合、ENTITY_REPLACEMENT_LIMIT
はテキストに出現できるノードの総数に対する制限を設定し、システムの過負荷を防ぎます。
getEntityCountInfoプロパティを使用した制限の見積り
制限に設定する必要がある値を分析するために、http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo
という特殊なプロパティを使用できます。Javaチュートリアルの処理制限サンプルに関する項の次のコード・スニペットは、プロパティの使用例を示しています。
public static final String ORACLE_JAXP_PROPERTY_PREFIX =
"http://www.oracle.com/xml/jaxp/properties/";
// ...
public static final String JDK_ENTITY_COUNT_INFO =
ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo";
// ...
parser.setProperty(JDK_ENTITY_COUNT_INFO, "yes");
W3C MathML 3.0のDTDで処理制限サンプルを実行すると、次の表が出力されます。
表12-5 W3C MathML 3.0のDTDを使用したJAXP処理制限サンプルの実行
プロパティ | 制限 | サイズ合計 | サイズ | エンティティ名 |
---|---|---|---|---|
ENTITY_EXPANSION_LIMIT |
64000 | 1417 | 0 | null |
MAX_OCCUR_NODE_LIMIT |
5000 | 0 | 0 | null |
ELEMENT_ATTRIBUTE_LIMIT |
10000 | 0 | 0 | null |
TOTAL_ENTITY_SIZE_LIMIT |
50000000 | 55425 | 0 | null |
GENERAL_ENTITY_SIZE_LIMIT |
0 | 0 | 0 | null |
PARAMETER_ENTITY_SIZE_LIMIT |
1000000 | 0 | 7303 | %MultiScriptExpression |
MAX_ELEMENT_DEPTH_LIMIT |
0 | 2 | 0 | null |
MAX_NAME_LIMIT |
1000 | 13 | 13 | null |
ENTITY_REPLACEMENT_LIMIT |
3000000 | 0 | 0 | null |
この例では、エンティティ参照の合計数(エンティティ展開)は1417で、デフォルトの上限は64000です。すべてのエンティティの合計サイズは55425で、デフォルトの上限は50000000です。最大のパラメータ・エンティティは、すべての参照が解決された後に7303の長さを持つ%MultiScriptExpression
です。デフォルトの上限は1000000です。
これがアプリケーションで処理されることが想定される最大ファイルである場合、制限は小さい数値に設定することをお薦めします。たとえば、ENTITY_EXPANSION_LIMIT
の場合は2000、TOTAL_ENTITY_SIZE_LIMIT
の場合は100000、PARAMETER_ENTITY_SIZE_LIMIT
の場合は10000です。
外部アクセス制限をいつ使用するか
XMLプロセッサは、デフォルトで、XMLソースで参照される外部リソースへの接続および読取りを試行します。これにより、アプリケーションおよびシステムは、外部接続によって発生するリスクに晒される可能性があることに注意してください。そのため、アプリケーションでは外部アクセス制限プロパティを使用した外部接続の制限を検討することをお薦めします。
信頼できるXMLドキュメントのみを処理する内部アプリケーションおよびシステムでは、これらの制限が不要な場合があります。外部接続を規制するためにJavaセキュリティ・マネージャに依存するアプリケーションおよびシステムでも、それらが不要な場合があります。ただし、外部アクセス制限はXMLプロセッサに固有であり、プロセスの最上位レイヤーにあることに注意してください。つまり、プロセッサは接続を行う前にこれらの制限をチェックします。したがって、外部接続リスクに対する、より直接的な追加の保護として機能します。
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。外部アクセス制限のプロパティをカスタムのリゾルバおよびカタログ(「リゾルバおよびカタログの使用」を参照)とともに使用すると、外部接続を効果的に管理し、リスクを軽減できます。
信頼できるソースを含む信頼できる環境であっても、外部アクセス制限とリゾルバの両方を使用して外部ソースへの依存を最小限にすることをお薦めします。
JAXPプロパティの使用
JAXPファクトリを使用したプロパティの設定
アプリケーションのコードを変更したり、新しいアプリケーションを作成する場合は、JAXPファクトリまたはパーサーを通じてJAXPプロパティを設定することをお薦めします。これらのプロパティは、次のインタフェースを使用して設定します。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(name, value);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.setProperty(name, value);
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
schemaFactory.setProperty(name, value);
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(name, value);
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);
XPathFactory xf = XPathFactory.newInstance();
xf.setProperty(name, value);
次に、処理制限の設定例を示します。
dbf.setAttribute("jdk.xml.entityExpansionLimit", "2000");
dbf.setAttribute("jdk.xml.totalEntitySizeLimit", "100000");
dbf.setAttribute("jdk.xml.maxParameterEntitySizeLimit", "10000");
dbf.setAttribute("jdk.xml.maxElementDepth", "100");
factory.setAttribute("jdk.xml.xpathTotalOpLimit", "1000");
xf.setProperty("jdk.xml.xpathExprGrpLimit", "20");
次に、DOMパーサーを外部DTDのローカル接続のみに制限する例を示します。
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "file, jar:file");
アプリケーション内のパーサー・モジュールが信頼できないソースを処理する場合、さらにアクセスを制限できます。次のコードは、jaxp.properties
ファイルおよびシステム・プロパティによって指定されたコードをオーバーライドし、XMLプロセッサがローカル・ファイルのみを読み取れるようにします。
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "file");
// ...
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "file");
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "file");
「JAXPプロパティの設定のスコープおよび順序」で説明したように、JAXPファクトリを通じて指定されたJAXPプロパティは、最も狭いスコープを持ち、ファクトリによって作成されたプロセッサにのみ影響するため、デフォルト設定、システム・プロパティおよびjaxp.properties
ファイル内の設定をオーバーライドします。JAXPファクトリを使用してJAXPプロパティを設定すると、使用しているJDKリリースや、JAXPプロパティを他の手段で設定するかどうかに関係なく、アプリケーションの動作が同じようになります。
システム・プロパティの使用
システム・プロパティは、アプリケーションのコードを変更できない場合に便利です。
JDKの起動全体に対してJAXPプロパティを設定するには、コマンド行で対応するシステム・プロパティを設定します。
JAXPプロパティをアプリケーションの一部のみに設定するには、対応するシステム・プロパティをその部分の前に設定し、後でクリアします。たとえば、アプリケーションで外部DTDおよびスキーマへのアクセスが必要な場合、これらの行をアプリケーションの初期化コード・ブロックに追加します。
System.setProperty("javax.xml.accessExternalDTD", "file, http");
System.setProperty("javax.xml.accessExternalSchema", "file, http");
その後、アプリケーションでXMLドキュメントの処理を実行した後、またはアプリケーションを終了する前に、次のようにプロパティをクリアします。
System.clearProperty("javax.xml.accessExternalDTD");
System.clearProperty("javax.xml.accessExternalSchema");
Javaチュートリアルの処理制限のサンプルからの次のコードは、処理制限maxGeneralEntitySizeLimit
に対してこれを行う方法を示す別の例です。
public static final String SP_GENERAL_ENTITY_SIZE_LIMIT =
"jdk.xml.maxGeneralEntitySizeLimit";
// Set limits using System property;
// this setting will affect all processing after it's set
System.setProperty(SP_GENERAL_ENTITY_SIZE_LIMIT, "2000");
// Perform some processing here
// After it is done, clear the property
System.clearProperty(SP_GENERAL_ENTITY_SIZE_LIMIT);
処理制限の値は整数であることに注意してください。処理制限の値が解析可能な整数でない場合はNumberFormatExceptionがスローされます。メソッドjava.lang.Integer.parseInt(String)を参照してください。
次の例では、アプリケーションの一部の外部スキーマを解決できます。
// Allow resolution of external schemas
// This setting will affect all processing after it's set
System.setProperty("javax.xml.accessExternalSchema", "file, http");
// Perform some processing here
// After it's done, clear the property
System.clearProperty("javax.xml.accessExternalSchema");
jaxp.propertiesファイルの使用
すべてのJDK呼出しに影響するJAXPプロパティを指定する場合は、<java-home>/conf/jaxp.properties
という名前の構成ファイルを作成し、その中の各行にJAXPプロパティの名前と値のペアを1つずつ指定します。たとえば、次のjaxp.properties
ファイルでは、maxGeneralEntitySizeLimit
処理制限プロパティを2000に設定し、stylesheet
処理命令、document
関数、およびimport
要素とinclude
要素によって設定される外部参照のファイルおよびHTTPプロトコルへのアクセスを制限します。
jdk.xml.maxGeneralEntitySizeLimit=2000
javax.xml.accessExternalStylesheet=file, http
XMLプロセッサによる外部接続を許可しない場合は、すべてのアクセス外部制限をfile
のみに設定できます。
javax.xml.accessExternalDTD=file
javax.xml.accessExternalSchema=file
javax.xml.accessExternalStylesheet=file
アプリケーションがXMLプロセッサを通じて外部ファイルを誤って読み取ることを防ぐには、jaxp.properties
ファイルで次のように外部アクセス制限を設定します。
javax.xml.accessExternalDTD=""
javax.xml.accessExternalSchema=""
javax.xml.accessExternalStylesheet=""
ノート:
jaxp.properties
ファイル内の対応するシステム・プロパティを使用します。処理制限システム・プロパティの接頭辞はjdk.xml
です。外部アクセス制限システム・プロパティの接頭辞はjavax.xml
です。- 処理制限値は整数です。処理制限の値が解析可能な整数でない場合はNumberFormatExceptionがスローされます。メソッドjava.lang.Integer.parseInt(String)を参照してください。
JAXPプロパティからのエラーの処理
JAXPプロパティを設定する際に、アプリケーションでorg.xml.sax.SAXNotRecognizedExceptionを捕捉することをお薦めします。これにより、それらをサポートしない古いリリースでアプリケーションが正しく動作します。
たとえば、Javaチュートリアルの処理制限のサンプルからのisNewPropertySupported
メソッドでは、JDK_GENERAL_ENTITY_SIZE_LIMIT
プロパティをサポートするバージョンのJDKでサンプルが実行されるかどうかが検出されます。
public boolean isNewPropertySupported() {
try {
SAXParser parser = getSAXParser(false, false, false);
parser.setProperty(JDK_GENERAL_ENTITY_SIZE_LIMIT, "10000");
} catch (ParserConfigurationException ex) {
fail(ex.getMessage());
} catch (SAXException ex) {
String err = ex.getMessage();
if (err.indexOf("Property '" + JDK_GENERAL_ENTITY_SIZE_LIMIT +
"' is not recognized.") > -1) {
// expected before this patch
debugPrint("New limit properties not supported. Samples not run.");
return false;
}
}
return true;
}
入力ファイルに、over-the-limit例外を引き起こすコンストラクトが含まれている場合、アプリケーションはエラー・コードをチェックして失敗の性質を判断できます。処理制限について、次のエラー・コードが定義されています。
EntityExpansionLimit
: JAXP00010001ElementAttributeLimit
: JAXP00010002MaxEntitySizeLimit
: JAXP00010003TotalEntitySizeLimit
: JAXP00010004MaxXMLNameLimit
: JAXP00010005maxElementDepth
: JAXP00010006EntityReplacementLimit
: JAXP00010007
エラー・コードの形式は、次のとおりです。
"JAXP" + components (two digits) + error category (two digits) + sequence number
したがって、コードJAXP00010001は、JAXPベース・パーサーのセキュリティ制限EntityExpansionLimit
を表します。
外部アクセス制限によって設定された制限が原因で外部リソースへのアクセスが拒否された場合、次の形式でエラーとともに例外がスローされます。
[type of construct]: Failed to read [type of construct]
"[name of the external resource]", because "[type of restriction]"
access is not allowed due to restriction set by the
[property name] property.
たとえば、次のように仮定します。
-
ACCESS_EXTERNAL_DTD
JAXPプロパティは次のように設定されます。parser.setProperty( "http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
-
アプリケーションは、外部DTDをHTTPプロトコルでフェッチしようとします。
-
パーサーは
http://www.example.com/dtd/properties.dtd
への外部参照を含むXMLファイルを解析しました。
エラー・メッセージは次のようになります。
External DTD: Failed to read external DTD
"http://www.example.com/dtd/properties.dtd", because "http"
access is not allowed due to restriction set by the
accessExternalDTD property.
XMLおよびJAXPプロパティ用のストリーミングAPI
XML (StAX)用のストリーミングAPI、JSR 173では、FSPがサポートされず、外部アクセス制限もサポートされません。一方、JDKのStAX実装では処理制限がサポートされ、JAXPのコンテキストでのStAXでは外部アクセス制限がサポートされます。
StAXおよび処理制限
JDKのStAX実装では、処理制限およびそれらに対応するシステム・プロパティがサポートされます。ただし、FSPはサポートされていないため、FSPをオンまたはオフにすることによってStAXの処理制限をオンまたはオフにすることはできません。処理制限は引き続き「処理制限用のJAXPプロパティ」に説明されているように動作します。
StAXおよび外部アクセスの制限
JDKのStAX実装では、外部アクセス制限に関連するJAXPプロパティがサポートされます。これらの設定はSAXまたはDOMに似ていますが、XMLInputFactory
クラスを使用します。たとえば:
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(
"http://javax.xml.XMLConstants/property/accessExternalDTD",
"file");
互換性を保つために、StAXのプロパティおよび機能は、処理制限および外部アクセス制限のプロパティよりも優先されます。たとえば、SupportDTD
プロパティをfalse
に設定すると、解析可能になる前に入力ファイルにDTDが含まれる場合に、プログラムによって例外がスローされます。したがって、DTDに対する処理制限および外部アクセス制限は、SupportDTD
プロパティをfalse
に設定することで無効化されているアプリケーションには影響しません。
拡張関数
TransformerおよびXPathに対してはセキュア処理機能(FSP)がデフォルトでオフになるため、拡張機能を使用できます。信頼できないソースからのドキュメントを処理するアプリケーションでは、拡張関数機能をオフにすることをお薦めします。これを行うには、次の2つの方法があります。
-
FSPをtrueに設定します。たとえば:
TransformerFactory tf = TransformerFactory.newInstance(); tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
-
enableExtensionFunctionsプロパティをfalseに設定します:
final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; // ... TransformerFactory tf = TransformerFactory.newInstance(); tf.setFeature(ENABLE_EXTENSION_FUNCTIONS, false);
Javaセキュリティ・マネージャをインストールした結果として拡張関数が無効になっている場合、アプリケーションでは、enableExtensionFunctionsプロパティをtrueに設定して拡張関数機能を再度有効にすることもできます。次の表で、このプロパティを定義します。
表12-6 enableExtensionFunctions
属性 | 説明 |
---|---|
名前 | http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions |
定義 | XSLTおよびXPath拡張関数が許可されるかどうかを決定します。 |
値 | ブール。Trueは拡張関数が許可されることを示します。それ以外の場合はFalseです。 |
デフォルト値 | true |
システム・プロパティ | jdk.xml.enableExtensionFunctions |
導入されたバージョン | 7u60 |
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。DTD処理の無効化
アプリケーションでDTDが必要ない場合は、DTD処理を無効化して、サービス拒否、XML外部エンティティ(XXE)、サーバー側リクエストの偽造(SSRF)など、多くの一般的なDTD関連の攻撃に対抗することを検討してください。
SAXおよびDOMパーサーに対するDTD処理の無効化
SAXおよびDOMパーサーのDTD処理を無効にするには、ファクトリを通じてhttp://apache.org/xml/features/disallow-doctype-decl
機能をtrueに設定します。次のコード・スニペットはSAXパーサーのDTDを無効化します。受け取ったXMLドキュメントにDOCTYPE宣言が含まれていると、致命的なエラーがスローされます。
final static String DISALLOW_DTD =
"http://apache.org/xml/features/disallow-doctype-decl";
// ...
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(DISALLOW_DTD, true);
StAXパーサーに対するDTD処理の無効化
StAXパーサーのDTD処理を無効化するには、プロパティSupportDTD
をXMLInputFactory.setPropertyメソッドで設定します。
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
リゾルバおよびカタログの使用
JDK XMLプロセッサでカスタム・リゾルバおよびカタログを登録して、外部リソースへの参照を捕捉し、ローカル・リソースで解決できます。この機能によって、外部リソースの読み取りとアクセスの必要がなくなるため、潜在的なリスクのソースを除去するのに役立ちます。
Java XMLリゾルバ
Java XML APIでは、JDK XMLプロセッサに登録して外部リソースを解決できる様々なリゾルバがサポートされます。これらのリゾルバには、SAXおよびDOMパーサー用のエンティティ・リゾルバ、StAXパーサー用のXMLリゾルバ、検証用のLSResourceResolverおよび変換用のURIResolverが含まれます。
SAXおよびDOMのエンティティ・リゾルバ
SAXは、DOMでもサポートされるインタフェースorg.xml.sax.EntityResolverを定義します。これにより、アプリケーションでエンティティ解決プロセスをトレース実行し、独自のタームでエンティティ解決を実行できます。インタフェースの定義は次のとおりです。
package org.xml.sax;
public interface EntityResolver {
public InputSource resolveEntity(String publicID, String systemID)
throws SAXException;
}
その後、SAXドライバでインタフェースの実装を登録できます。
EntityResolver resolver = ...;
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(resolver);
または、DOMビルダーで登録できます。
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
docBuilder.setEntityResolver(resolver);
StAX用のXMLResolver
StAXでは、javax.xml.stream.XMLResolverインタフェースを定義します。
package javax.xml.stream;
public interface XMLResolver {
public Object resolveEntity(
String publicID, String systemID,
String baseURI, String namespace)
throws XMLStreamException;
}
これをStAXファクトリに登録できます。
XMLResolver resolver = ...;
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.RESOLVER, resolver);
javax.xml.transform用のURIResolver
javax.xml.transform APIでは、URIResolverインタフェースを介した外部リソースのカスタム解決がサポートされます。
package javax.xml.transform;
public interface URIResolver {
public Source resolve(String href, String base)
throws TransformerException;
}
URIResolverの実装は、次のようにトランスフォーマに登録できます。
URIResolver resolver = ...;
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t =
tf.newTransformer(new StreamSource(
new StringReader("xsl source")));
t.setURIResolver(resolver);
javax.xml.validation用のLSResourceResolver
javax.xml.validation APIでは、LSResourceResolverインタフェースを通じてDocument Object Model Level 3 Load and Save (DOM LS) DOMがサポートされます。
package org.w3c.dom.ls;
public interface LSResourceResolver {
public LSInput resolveResource(
String type, String namespaceURI, String publicId,
String systemId, String baseURI);
}
LSResourceResolverの実装は、次のようにSchemaFactoryに登録できます。
SchemaFactory schemaFactory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
LSResourceResolver resolver = ...;
schemaFactory.setResourceResolver(resolver);
カタログAPI
XML Catalog APIでは、Organization for the Advancement of Structured Information Standards (OASIS) XMLカタログ、OASIS標準V1.1がサポートされます。このAPIは、JDK XMLプロセッサによって完全に実装されており、使用が簡単です。『Java Platform, Standard Editionコア・ライブラリ』の「XMLカタログAPI」を参照してください。
XMLカタログAPIを使用して、外部リソースをCatalogResolverインタフェースで解決し、JDK XMLプロセッサ上でカタログを有効化します。
カタログ・リゾルバ
カタログ・オブジェクトとして構成されたローカル・リソースで外部参照を置き換えるカスタム・リゾルバとしてCatalogResolverを使用できます。「Java XMLリゾルバ」で説明されているように、EntityResolver、XMLResolver、URIResolverまたはLSResourceResolverのかわりにCatalogResolverをファクトリまたはプロセッサに登録できます。次のコード・スニペットでは、CatalogResolverがSAXParserFactoryにEntityResolverとして登録されます。
URI catalogUri = URI.create("file:///users/auser/catalog/catalog.xml")
CatalogResolver cr =
CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(cr);
JDK XMLプロセッサでのカタログの有効化
JDK XMLプロセッサは、カタログAPIをネイティブ機能として実装します。したがって、プロセッサの外部でCatalogResolverをインスタンス化する必要はありません。必要なのは、setPropertyメソッド、setAttributeメソッドまたはシステム・プロパティを使用して、またはjaxp.properties
ファイル内で、XMLプロセッサにカタログ・ファイルを登録することだけです。XMLプロセッサによって自動的にカタログを使用したマッピングが実行されます。次のコード・スニペットは、XMLInputFactoryを使用してStAXパーサーにカタログを登録する方法を示しています。
String catalog = "file:///users/auser/catalog/catalog.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
詳細は、『Java Platform, Standard Editionコア・ライブラリ』の「XMLカタログAPI」を参照してください。
サードパーティ製パーサー
JDKでは、クラスパスにサードパーティ製のパーサーが存在する場合でも、常にシステムデフォルト・パーサーが使用されます。JDKのシステムデフォルト・パーサーをオーバーライドするには、jdk.xml.overrideDefaultParser
プロパティをtrueに設定します。
表12-7 overrideDefaultParser
属性 | 説明 |
---|---|
名前 | jdk.xml.overrideDefaultParser |
定義 | サードパーティのパーサー実装を使用して、JDKのトランスフォーマ、バリデータおよびXPath実装のシステムデフォルト・パーサーをオーバーライドできるようにします。このプロパティは、JAXPファクトリ、システム・プロパティまたはjaxp.properties ファイルを通じて設定できます。
|
値 | ブール。trueに設定すると、XML変換、XML検証またはXPath操作中にサードパーティ製パーサーの実装でシステムデフォルト実装をオーバーライドできます。falseに設定すると、サードパーティ製パーサー実装の使用が無効になります。値が文字列として指定されている場合、戻り値はBoolean.parseBooleanの値になります。 |
デフォルト値 | false |
システム・プロパティ | jdk.xml.overrideDefaultParser |
導入されたバージョン | 6u181、7u171、8u161、9.0.4 |
次のコード・スニペットは、setFeatureメソッドでjdk.xml.overrideDefaultParser
プロパティを設定して、サードパーティ製パーサー(クラスパス上にある場合)を使用するようにファクトリに指示しています。
static final String JDK_OVERRIDE_PARSER = "jdk.xml.overrideDefaultParser";
...
TransformerFactory tFactory = TransformerFactory.newInstance();
tFactory.setFeature(JDK_OVERRIDE_PARSER, true);
...
XPathFactory xf = XPathFactory.newInstance();
xf.setFeature(JDK_OVERRIDE_PARSER, true);
...
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setFeature(JDK_OVERRIDE_PARSER, true);
...
Schema schema = schemaFactory.newSchema(new File("mySchema.xsd"));
Validator validator = schema.newValidator();
validator.setFeature(JDK_OVERRIDE_PARSER, true);
次のコード・スニペットは、jdk.xml.overrideDefaultParser
をシステム・プロパティとして設定しています。
System.setProperty("jdk.xml.overrideDefaultParser", "true"));
jaxp.properties
ファイルに次の行を追加すると、サードパーティ製パーサーを有効にできます。
jdk.xml.overrideDefaultParser=true
JAXPセキュリティに関する一般的な推奨事項
アプリケーションおよびシステムのセキュリティを確保するためのJAXPのプロパティと機能の構成に関する一般的な推奨事項を次に示します。
- セキュア処理機能(FSP)をオンにしてから、特定の要件に従って個々の機能とプロパティを調整します。
- 処理制限では、アプリケーションが必要とする最大量に対応できるだけの大きさになるように調整します。
- 外部アクセス制限の場合は、リゾルバの使用を含め、アプリケーションの外部リソースへの依存を軽減または排除してから、これらの制限を強化します。
- ローカル・カタログを設定し、すべてのXMLプロセッサでカタログAPIを有効にして、アプリケーションの外部リソースへの依存をさらに軽減します。
付録A: Java API for XML Processingの用語および定義の用語集
表12-8 JAXP用語集
用語 | 定義 |
---|---|
JAXP | Java API for XML Processing |
Java SE XML API | JAXP JSRに定義され、Java SEに統合されているAPI |
Java XML API | Java SE XML APIと同等の用語 |
Java XMLの機能およびプロパティ | Java SEの仕様で定義されているXML関連の機能とプロパティ |
java.xml | java.xmlモジュール |
JDK XML | Java XML APIのJDK実装 |
JDK XMLパーサー | XMLパーサーのJDK実装 |
JDK XMLプロパティ | JDK実装専用プロパティ |
FSP | FEATURE_SECURE_PROCESSING |
付録B: JavaおよびJDK XMLの機能とプロパティの命名規則
JavaおよびJDK XMLの機能とプロパティは、javax.xml.XMLConstantsクラスに定義されています。この機能には、接頭辞http://javax.xml.XMLConstants/feature
、プロパティhttp://javax.xml.XMLConstants/property
があります。対応するシステム・プロパティがある場合、その接頭辞はjavax.xml
です。
JDK XMLプロパティは、JDK実装専用のプロパティです。プロパティの接頭辞は、JDK 8以前の場合はhttp://www.oracle.com
、JDK 9以降の場合はjdk.xml
です。次の表に、この命名規則をまとめます。
表12-9 JavaおよびJDK XMLの機能とプロパティの命名規則
スコープ | APIプロパティ接頭辞 | システム・プロパティ接頭辞 | Java SEおよびJDKバージョン |
---|---|---|---|
Java SE |
|
javax.xml |
1.4以降 |
JDK | http://www.oracle.com/xml/jaxp/properties |
jdk.xml |
7以降 |
JDK | jdk.xml |
jdk.xml |
9以降 |