53

C# アプリケーションで XML ドキュメントを解析しようとすると、次のエラーが発生します。

「セキュリティ上の理由から、この XML ドキュメントでは DTD が禁止されています。DTD 処理を有効にするには、XmlReaderSettings の ProhibitDtd プロパティを false に設定し、その設定を XmlReader.Create メソッドに渡します。」

参考までに、次のコードの 2 行目で例外が発生しました。

using (XmlReader reader = XmlReader.Create(uri))
{
    reader.MoveToContent(); //here

    while (reader.Read()) //(code to parse xml doc follows).

Xml に関する私の知識はかなり限られており、DTD 処理とは何か、エラー メッセージが示唆することをどのように行うかについてもわかりません。これを引き起こしている可能性があるものと、それを修正する方法について何か助けはありますか? ありがとう...

4

4 に答える 4

78

まず、いくつかの背景。

DTD とは何ですか?

解析しようとしているドキュメントには、ドキュメント タイプの宣言が含まれています。ドキュメントを見る<!DOCTYPEと、対応する>. このような宣言により、XML プロセッサは、一連の要素と属性を指定し、保持できる値や内容を制限する一連の宣言に対してドキュメントを検証できます。

エンティティも DTD で宣言されるため、DTD を使用すると、プロセッサはエンティティへの参照を展開する方法を知ることができます。(エンティティpubdateは、「2012 年 12 月 15 日」のようにドキュメントの発行日を含むように定義され、ドキュメント内で次のように数回参照される場合があります&pubdate;。実際の日付はエンティティ宣言で 1 回だけ与えられるため、この使用法はドキュメント内の発行日へのさまざまな参照を互いに一貫性を保つことが容易になります。)

DTD とはどういう意味ですか?

ドキュメント タイプの宣言には、純粋に宣言的な意味があります。このドキュメント タイプのスキーマは、XML 仕様で定義された構文で、このような場所で見つけることができます。

XML の基礎をよく理解していない人が作成したソフトウェアの中には、宣言の意味について初歩的な混乱に悩まされているものがあります。文書型宣言の意味は宣言的(スキーマはそこにあります) ではなく、命令的(この文書を検証してください) であると想定しています。あなたが使用しているパーサーはそのようなパーサーのようです。文書型宣言を持つ XML 文書を渡すことで、何らかの処理を要求したと見なされます。その作成者は、ユーザーから実行時パラメーターを受け入れる方法に関する改善コースから恩恵を受ける可能性があります。(宣言型セマンティクスを理解するのがいかに難しいかがわかるでしょう。一部の XML パーサーの作成者でさえ、時にはそれらを理解できず、代わりに命令型の考え方に陥ることがあります。ため息です。)

彼らが話しているこれらの「セキュリティ上の理由」は何ですか?

一部のセキュリティ志向の人々は、DTD 処理 (検証、または検証なしのエンティティ展開) がセキュリティ リスクを構成すると判断しました。エンティティ展開を使用すると、すべてのエンティティが完全に展開されると非常に大きなドキュメントに展開される、非常に小さな XML データ ストリームを簡単に作成できます。詳しく知りたい場合は、いわゆる「10 億の笑い攻撃」に関する情報を検索してください。

10 億の笑い攻撃から保護するための明白な方法の 1 つは、ユーザーが提供したデータまたは信頼できないデータに対してパーサーを呼び出す人が、解析プロセスが消費できるメモリの量または時間を制限する環境でパーサーを呼び出すことです。このようなリソース制限は、1960 年代半ば以降、オペレーティング システムの標準的な部分になっています。理由は私にはわかりませんが、一部のセキュリティ志向の人々は、正しい答えはリソース制限なしで信頼できない入力に対してパーサーを実行することであると信じており、入力の検証を不可能にする限りこれは安全であると信じています合意されたスキーマに対して。

これが、システムがデータにセキュリティ上の問題があることを通知している理由です。

一部の人々にとって、DTD がセキュリティ リスクであるという考えは、良識というよりもパラノイアのように聞こえますが、私はそれらが正しいとは思いません。(a) 健全なパラノイアは、セキュリティの専門家が人生で必要としているものであり、(b) セキュリティに本当に関心のある人は、いずれにしてもリソース制限を主張するだろうということを覚えておいてください。解析プロセスにリソース制限がある場合、DTD は無害。DTD の禁止はパラノイアではなくフェティシズムです。


さて、その背景を邪魔にならないように...

どのように問題を解決しますか?

最良の解決策は、ベンダーが XML セキュリティに関する老婆の話にだまされていることを痛烈に訴え、ベンダーがセキュリティを気にするのであれば、DTD を禁止するのではなく、合理的なセキュリティ分析を行うべきだと伝えることです。

一方、メッセージが示すように、「XmlReaderSettings の ProhibitDtd プロパティを false に設定し、その設定を XmlReader.Create メソッドに渡す」ことができます。入力が実際に信頼されていない場合は、プロセスに適切なリソース制限を与える方法を検討することもできます。

また、フォールバックとして (これはお勧めしません)、入力のドキュメント タイプ宣言をコメント アウトできます。

于 2012-12-13T19:59:14.860 に答える
29

これを修正する限り、少し調べてみると、次のように簡単に追加できることがわかりました。

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;

これらの設定を create メソッドに渡します。

[2017 年 3 月 9 日更新]

一部の人が指摘しているように、.ProhibitDTDT は非推奨になりました。以下のアーロン・ディシュノ博士の回答は、代替ソリューションを示しています

于 2012-12-19T16:50:03.760 に答える