web-dev-qa-db-ja.com

XXE攻撃を防ぐ方法(.netのXmlDocument)

コードのセキュリティ監査を実施したところ、コードにはEXternal Entity(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)にロードする値がないことがわかります。誰かが私が物を見落としているところを手伝ってくれる?誰でも助けていただければ幸いです!

31
junni lomo

外部リソースは、_XmlDocument.XmlResolver_プロパティを介して提供される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いくつかのアイデアがあります。ResolveUri()からnullを返すだけですsaveこの種の攻撃からのコードURIが許可されている場合は、デフォルトのXmlUrlResolver.ResolveUri()実装を返すだけです。

それを使用するには:

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

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

37
Adriano Repetti

使用するのが良い

new XmlDocument { XmlResolver = null };

興味深いことに、.net 4.5.2と4.6から、デフォルトのリゾルバーは異なる動作をし、XmlUrlResolverを事前に使用して暗黙的にURLまたは場所を解決していません。

//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(); 
3
mousetwentytwo