38

コードのセキュリティ監査を行いましたが、コードは外部エンティティ(XXE)攻撃に対して脆弱であるとのことでした。私は次のコードを使用しています-

string OurOutputXMLString=
"<ce><input><transaction><length>00000</length><tran_type>Login</tran_type></transaction><user><user_id>ce_userid</user_id><subscriber_name>ce_subscribername</subscriber_name><subscriber_id>ce_subscriberid</subscriber_id><group_id>ce_groupid</group_id><permissions></permissions></user><consumer><login_details><username>UnitTester9</username><password>pDhE5AsKBHw85Sqgg6qdKQ==</password><pin>tOlkiae9epM=</pin></login_details></consumer></input></ce>"

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(OurOutputXMLString);

監査レポートでは、XMLエンティティに意図された制御の範囲外で解決できるURLが含まれている可能性があるため、失敗していると述べています。XMLエンティティリゾルバーは、外部参照の解決と取得を試みます。攻撃者が制御するXMLをこれらの機能のいずれかに送信できる場合、攻撃者は内部ネットワーク、ローカルファイルシステム、またはその他の機密データに関する情報にアクセスする可能性があります。これを回避するために、次のコードを記述しましたが、機能しません。

MemoryStream stream =
    new MemoryStream(System.Text.Encoding.Default.GetBytes(OurOutputXMLString));

XmlReaderSettings settings = new XmlReaderSettings();

settings.DtdProcessing = DtdProcessing.Prohibit;
settings.MaxCharactersFromEntities = 6000;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);

しかし、ここでは、リーダーにロードする値がないことがわかりますxmlDoc(XmlDocument)。誰かが私が物事を逃しているところを助けることができますか?

4

3 に答える 3

51

外部リソースは、XmlResolver提供されたviaXmlDocument.XmlResolverプロパティを使用して解決されます。XMLドキュメントに**外部リソース**(DTDやスキーマなど)を含める必要がない場合は、このプロパティをnull次のように設定するだけです。

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(OurOutputXMLString);

これらのURLの取得元をフィルタリングする場合(たとえば、特定のドメインのみを許可する場合)は、独自のクラスを派生させ、メソッドXmlUrlResolverをオーバーライドするだけです。ResolveUri()そこで、URLが何であるかを確認し、それをサニタイズできます(たとえば、ローカルネットワーク内または信頼できるソースからのURLのみを許可できます)。

例えば:

class CustomUrlResovler : XmlUrlResolver
{
    public override Uri ResolveUri(Uri baseUri, string relativeUri)
    {
        Uri uri = new Uri(baseUri, relativeUri);
        if (IsUnsafeHost(uri.Host))
            return null;

        return base.ResolveUri(baseUri, relativeUri);
    }

    private bool IsUnsafeHost(string host)
    {
        return false; 
    }
}

IsUnsafeHost()指定されたホストが許可されているかどうかをチェックするカスタム関数はどこにありますか。いくつかのアイデアについては、SOに関するこの投稿を参照してください。この種の攻撃からコードを保存nullするには、から戻ってください。URIが許可されている場合は、デフォルトの実装を返すだけです。ResolveUri()XmlUrlResolver.ResolveUri()

それを使用するには:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = new CustomUrlResolver();
xmlDoc.LoadXml(OurOutputXMLString);

XML外部リソースの解決方法の詳細については、MSDocsの外部リソースの解決を参照してください。コードがこの例よりも複雑な場合は、 XmlDocument.XmlResolverプロパティの備考セクションを必ずお読みください。

于 2013-01-09T08:40:18.427 に答える
6

したがって、使用する方が良いです

new XmlDocument { XmlResolver = null };

興味深いことに、.net 4.5.2および4.6とは異なり、デフォルトのリゾルバーの動作は異なり、私が見たように、URLまたは場所を解決するためにXmlUrlResolverを暗黙的に使用しません。

//In pre 4.5.2 it is a security issue.
//In 4.5.2 it will not resolve any more the url references in dtd and such, 
//Still better to avoid the below since it will trigger security warnings.
new XmlDocument(); 
于 2016-11-23T17:06:26.850 に答える
0

XmlReaderSettings.DtdProcessingをDtdProcessing.Prohibitに設定すると、.NET4.7.2では完全に正常に機能します。これが私がテストしていたものです。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo 
[
  <!ELEMENT demo ANY >
  <!ENTITY % extentity SYSTEM "https://www.hl7.org/documentcenter/public/wg/structure/CDA.xsl">
  %extentity;
]>
<test>
    Some random content
</test>

上記のコンテンツをファイルに保存し、次のc#コードのフラグメントからファイルを読み取ります。

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.MaxCharactersFromEntities = 6000;
//The following stream should be the filestream of the above content.
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);

次の例外が発生します。

For security reasons DTD is prohibited in this XML document. To enable DTD 
processing set the DtdProcessing property on XmlReaderSettings to Parse and 
pass the settings into XmlReader.Create method.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
at System.Xml.XmlDocument.Load(XmlReader reader)
于 2020-12-19T05:16:54.700 に答える