2 Oracle XML Developer's Kitのセキュリティ上の考慮事項
この章では、XDKを使用して構築されたソフトウェア・プログラムの使用時に実行されるセキュリティ手段について説明します。
2.1 Javaのセキュリティの実装
Javaプログラムのセキュリティを実装するプロセス。
2.1.1 Oracle XML Developer's Kitを使用したXSLT処理の保護
XSLT処理のためにOracle XML Developer's Kitを使用する前に、いくつかの構成オプションを設定して保護する必要があります。
次のように、XSLProcessor
APIとJAXPトランスフォーマAPIの両方でセキュアな処理を有効にする必要があります。
-
このJavaコードを使用して、
XSLProcessor
のセキュアな処理モードを有効にします。processor.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-
JAXPトランスフォーマAPIの
SAXTransformerFactory
のセキュアな処理モードを有効にするには、次のJavaコードを使用します。factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
これらの設定によって、次のようにXML解析セキュリティが向上します。
-
デフォルトでは、この設定によって外部リソースへのアクセスがブロックされます。
開発者は、XSLスタイルシートの
include
要素およびimport
要素を解決するために、org.xml.sax.EntityResolver
またはjavax.xml.transform.URIResolver
を使用できるようになります。JavaインタフェースURIResolver
を使用して、信頼できる外部リソースへのXPath関数またはXSLT関数のアクセスを提供できます。 -
設定によってJavaリフレクションの使用がブロックされ、Javaコードが実行されます。
開発者は、信頼できるJavaクラスをインタフェース
javax.xml.xpath.XPathFunction
に変換し、インタフェースjavax.xml.xpath.XPathFunctionResolver
を使用して解決できます。 -
設定によって再帰エンティティ拡張が制限されます。
これにより、過剰なリソース消費による一般的なサービス拒否攻撃を防ぐことができます。
注意:
これにより、再帰的なエンティティ拡張を制限できますが、XDKではXML変換中はリソース消費を制限できません。XSLスタイルシートには無限ループを含められます。含めない場合、リソースは大幅に消費されます。このため、信頼できないソースまたは外部エンティティからXSLスタイルシートを受け入れることはできません。使用されているすべてのスタイルシートをテストし、過剰なリソースが消費されないようにします。
さらに、ユーザーまたは外部の信頼できないエンティティから取得されるデータまたはファイルのXSLT処理を実行するすべてのコードは、XSLProcessor APIとJAXPトランスフォーマAPIの両方でセキュアな処理が有効になっていることを確認します。これを行わないと、セキュリティの脆弱性を開放してしまいます。XSLプロセッサが保護されると、外部リソースへのアクセスおよびJava拡張関数の実行は許可されません。
任意のセキュリティ免除
セキュリティ制限を任意でオーバーライドする場合は、次のオプションを使用できます。
-
次のいずれかの変更を実行して、一部の外部ソースへのアクセスを許可します。
-
メソッド
setURIResolver()
を使用して、URIResolver
をSAXTransformerFactory
またはXSLProcessor
に設定します。 -
メソッド
setEntityResolver()
を使用して、EntityResolver
をXSLProcessor
に設定します。
-
-
Javaインタフェース
oracle.xml.xslt.XSLSecurityManager
を使用して、Javaリフレクション拡張機能を使用できるJavaクラスとメソッドのホワイトリストを登録します。 -
XSLProcessor
のメソッドsetAttribute()
を使用してXSLSecurityManager
を登録し、安全であるとわかっている拡張関数を実行します。processor.setAttribute(XSLProcessor.SECURITY_MANAGER, securityManager);
-
XSLSecurityManager
の単純なAPIを使用して、Javaクラスおよびメソッドのホワイトリストを実装します。boolean checkExtensionFunction(String className, String fnName);
2.1.2 Oracle XML Parserの安全な使用
多くのXMLパーサーと同様に、XDKパーサーはデフォルトで外部参照の解決を試みます。攻撃者は、この動作を悪用してXML外部エンティティ(XXE)攻撃およびXMLエンティティ拡張(XEE)攻撃を実行できます。この脆弱性を回避するには、外部リソースへの任意の参照の使用を無効にし、制約のないエンティティ拡張を無効にします。
システム内に作成されたすべてのパーサーを外部エンティティの使用からブロックするグローバル・セキュリティ設定を実装するには、Javaシステム・プロパティoracle.xdkjava.security.resolveEntityDefault
をfalse
に設定します。
特定のパーサーのエンティティ拡張をブロックしたり、エンティティ拡張のレベル数を制限するには、属性XMLParser.RESOLVE_ENTITY_DEFAULT
またはXMLParser.ENTITY_EXPANSION_DEPTH
をパーサーに設定します。
次に例を示します。
DOMParser domParser = new DOMParser(); // Extend oracle.xml.parser.v2.XMLParser
domParser.setAttribute(DOMParser.EXPAND_ENTITYREF, false); // Do not expand entity references
domParser.setAttribute(DOMParser.DTD_OBJECT, dtdObj); // dtdObj is an instance of oracle.xml.parser.v2.DTD
domParser.setAttribute(DOMParser.ENTITY_EXPANSION_DEPTH, 12); // Do not allow more than 11 levels of entity expansion
JAXPを使用してXML解析を行う場合は、DocumentBuilderFactory
またはSAXParserFactor
に対してFEATURE_SECURE_PROCESSING
をtrue
に設定します。これにより、外部エンティティの拡張がブロックされ、エンティティ拡張が深さ11に制限され、エンティティ拡張数が64000に制限されます。
my_factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
関連項目:
例2-1 XMLパーサーを使用するJavaコードの安全性の向上
このJavaスニペットは、外部エンティティの解決をブロックし、エンティティ拡張レベルの数を制限し、エンティティ拡張の数を制限します。
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false); // Disable expanding of entities
try {
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
} catch (Throwable e) {
//handle old parser version
...
}
DocumentBuilder dp = dbf.newDocumentBuilder();
// Make resolveEntity just throw an exception.
// (If you really need to support external references
// then resolve publicId only against trusted values.)
dp.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId, String systemId)
throws DOMException, IOException {
throw new DOMException((short)0, "Security Violation");
}
});
...
2.2 Cのセキュリティの実装
Cプログラムのセキュリティを実装するプロセス。
安全でないアクセスのブロック
通常、XXE攻撃のリスクを負うXDK C APIの2つのセットがあります。1セットは関数LpxInitEncoded()
を使用し、もう1セットは関数XmlCreate()
またはXmlCreateNew()
を使用します
LpxInitEncoded()
の場合、フラグLPX_FLAG_URL_DONT_OPEN
およびLPX_FLAG_FILE_DONT_OPEN
をパーサーAPIにフィードして、外部リソース・アクセスをブロックします。
次に例を示します。
LpxBufferParse ( ctx,
(oratext *) buf,
(size_t) lstlen ( buf ),
(oratext *) "UTF-8", (lx_langid) 0, (lxglo *) 0,
LPX_FLAG_URL_DONT_OPEN | LPX_FLAG_FILE_DONT_OPEN);
XmlCreate()
またはXmlCreateNew()
の場合、コンテキストxctx
の作成時にパラメータno_ri_open
をTRUE
に設定します。この設定により、xctx
を使用するパーサーAPIの安全でないアクセスがブロックされます。
次に例を示します。
xctx = XmlCreateNew(&xerr, (oratext *) "test",
(oratext **)NULL, 0, (oratext *)NULL,
"data_encoding", “AL32UTF8”,
"input_encoding", "AL32UTF8",
"no_ri_open", "TRUE", /* disallow URI resolution */
"error_handler", test_errmsg,
NULL);
安全でないアクセスをブロックするために、DOM APIでパラメータno_ri_open
をTRUE
に設定することもできます。DOM APIでこのフラグを設定すると、このフラグがXmlCreate()
で設定されていない場合でもセキュリティが強制されます。
次に例を示します。
doc = XmlLoadDom(xctx, &xerr,
"file", filename,
"discard_whitespace", TRUE,
"validate", TRUE,
"no_ri_open", TRUE, /* disallow URI resolution */
NULL);
任意のアクセスを許可
ユーザーが外部リソースへの任意の参照を許可したり、アクセスをユーザー自身のコントロールの下で行ったりする場合、次のステップを実装できます。
-
前の例で示した場所で
no_ri_open
をFALSE
に設定します。 -
カスタマイズされたオープン、読取りおよびクローズのコールバック関数を開発し、これらの関数を使用して
OraSteam
を初期化します。 -
xctx
へのアクセスをOraSteam
でオーバーライドします
次に例を示します。
ostream = OraStreamInit(actx, (oratext *)"test", &oerr,
"open", http_open,
"read", http_read,
"close", http_close,
NULL);
xerr = XmlAccess(xctx, XML_ACCESS_HTTP, ostream);
このコードは、3つのコールバックによって、ostream
のインスタンスを作成します。作成されたストリームは、XmlAccess
を使用してxctx
内のアクセスをオーバーライドします。xctx
はXmlLoadDom
などのAPIを呼び出すときに使用されます。したがって、ユーザーには外部リソースにアクセスできるルールを作成する選択肢があります。
2.3 C++のセキュリティ
デフォルトでは、C++ APIは外部リソースへのアクセスをブロックするため、セキュリティが保証されます。ただし、ユーザーはこのセキュリティ制限をオーバーライドし、自分の判断に基づいて外部リソースへの任意の参照を許可できます。
xmlctx.hpp
ヘッダー・ファイルでは、CXmlCtx(bool no_ri_open)
APIを使用してxctx
コンテキストを初期化し、パラメータno_ri_open
を設定します。no_ri_open
パラメータがtrue
に設定されている場合、xctx
を使用するパーサーAPIは外部リソースにアクセスできません。no_ri_open
パラメータをfalse
に設定すると、xctx
を使用するパーサーAPIは外部リソースにアクセスできます。
デフォルトでは、xctx
を使用するパーサーAPIは外部リソースにアクセスできません。アクセスを許可するには、次に示すようにno_ri_open
パラメータをfalse
に設定します。
xctx = CXmlCtx(FALSE); /* allow URI resolution */
注意:
外部リソースへのアクセスを許可すると、XML外部エンティティ(XXE)およびXMLエンティティ拡張(XEE)攻撃が発生する場合があります。セキュリティ制限をオーバーライドし、外部リソースへのアクセスを許可する場合は、注意が必要です。