0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

XXEと.NET Framework (SgmlReaderDll.dll)

Last updated at Posted at 2019-05-15

XXEと.NET Framework (SgmlReaderDll.dll)

XXEとは

XXE(XML External Entity)とは、XMLの外部参照機能を利用して、サーバ内部のファイル内容を取得(漏えい)したり、内部ネットワーク上のファイルにアクセスしたりする不正行為

XXEは、XMLを扱うアプリケーションで発現する可能性があるので、XML文書を取り扱う際には注意する必要がある。

SgmlReaderDll.dll

SGMLReader(SgmlReaderDll.dll)は、ゆるくXML解釈してくれるので、HTMLをDOM化する際によく使われているのではないかと思う。

一部のHTMLタグだけ許可する」のサンプルコードとしてもHTMLのDOM化に使っている

結論

SGMLReader(SgmlReaderDll.dll)には、XXEは発現しないようだ。

SGMLReaderも最終的には、System.Xml.XmlDocumentクラスに渡るので、念のためにSystem.Xml.XmlDocument#XmlResolver プロパティを「NULL」にしても良いかもしれない。

なぜSystem.Xml.XmlDocument#XmlResolver プロパティをNULLにした方がよいのか(System.Xml.XmlDocumentクラスのXXE対策)は、「XXEと.NET Framework」を参照してくれ。

SgmlReaderDll.dllとXXE

読み込むXMLファイル(in1.xml)はここ

SgmlReaderDll.dllとXXE(HTMLモードで、IgnoreDtd=True で、XmlResolverは無指定)

こんな感じ
XXEが発現していない。

079.png

SgmlReaderDll.dllとXXE(HTMLモードで、IgnoreDtd=False で、XmlResolverは無指定)

こんな感じ。in1.xmlには DTDがないので、そりゃぁ~、例外を吐くでしょうね。

080.png

SgmlReaderDll.dllとXXE(XMLモードで、IgnoreDtd=True で、XmlResolverは無指定)

こんな感じ。
XXEが発現していない。

081.png

SgmlReaderDll.dllとXXE(XMLモードで、IgnoreDtd=False で、XmlResolverは無指定)

こんな感じ。
XXEが発現していない。

082.png

SgmlReaderDll.dllとXXE

もう飽きた。

上記のテスト結果だと、SGMLReader(SgmlReaderDll.dll)には、XXEは発現しないようだ。

とはいえ、
SGMLReaderも最終的には、System.Xml.XmlDocumentクラスに渡るので、念のためにSystem.Xml.XmlDocument#XmlResolver プロパティを「NULL」にしても良いかもしれない。

ソースコード見たら・・・

SGMLReader(SgmlReaderDll.dll)のソースコードを見たら、2530行目辺りに「ResolveEntity()」のオーバーライドがあって、

// We never return any entity reference nodes, so this should never be called.

というコメントが確認できる。

つまり、SGMLReader(SgmlReaderDll.dll)を使う場合は、XXE脆弱性はないという事でよいのではないか

ソースコード(Program.cs)

XXEと.NET Frameworkとほぼ同様だが、SGMLReader(SgmlReaderDll.dll)を参照設定する必要がある

Program.cs
using System;
using System.IO;
using System.Xml;

namespace XMLandXXEtest{
    class Program{
        static void Main(string[] args){
            Boolean Isresolve = true;
            exXmlResolver myExXmlResolver = null;
            if (3 < args.Length) {
                if (args[3].ToLower() == "null"){
                    Isresolve = false;
                }else {
                    myExXmlResolver = new exXmlResolver();
                }
            }
            if (args.Length < 3) {
                Console.WriteLine("usage: XMLandXXEtest.exe <<xmlFile>> <<HTML|XML>> <<T|F|N>> [NotResolve]");
            }else{

                StreamReader sr = new StreamReader(new FileStream(args[0], FileMode.Open, FileAccess.Read));
                String str = sr.ReadToEnd();
                sr.Close();

                Sgml.SgmlReader tempSgmlReader = new Sgml.SgmlReader();
                tempSgmlReader.DocType = args[1];
                switch(args[2].ToLower()){
                    case "t":
                        tempSgmlReader.IgnoreDtd = true;
                        break;
                    case "f":
                        tempSgmlReader.IgnoreDtd = false;
                        break;
                    default:
                        break;
                }

                StringReader tempStringReader = new StringReader(str);
                tempSgmlReader.InputStream = tempStringReader;

                XmlDocument tempXmlDocument = new XmlDocument();
                // tempXmlDocument.XmlResolver = null; // 本番では念のためにコメントアウトした方がよい
                if (Isresolve == false){
                    tempXmlDocument.XmlResolver = null;
                }else if (myExXmlResolver != null){
                    tempXmlDocument.XmlResolver = myExXmlResolver;
                }
                tempXmlDocument.Load(tempSgmlReader);
                Console.WriteLine("after XML Resolve is (OuterXml)");
                Console.WriteLine(tempXmlDocument.OuterXml);
                Console.WriteLine("----------------------------------");
                Console.WriteLine("after XML Resolve is (InnerXml)");
                Console.WriteLine(tempXmlDocument.InnerXml);
                Console.WriteLine("----------------------------------");
                Console.WriteLine("after XML Resolve is (InnerText)");
                Console.WriteLine(tempXmlDocument.InnerText);
                Console.WriteLine("----------Detail------------------");
                foreach (XmlNode x in tempXmlDocument.ChildNodes){
                    WroteXMLnode(x, "");
                }
            }
        }
        static void WroteXMLnode(XmlNode node, String spaceStr) {
            Console.WriteLine(spaceStr + "name=" + node.Name + ", type=" + node.NodeType.ToString());
            Console.WriteLine(spaceStr + "valT=" + node.InnerText);
            Console.WriteLine(spaceStr + "valX=" + node.InnerXml);
            if (node.HasChildNodes == true){
                foreach (XmlNode x in node.ChildNodes){
                    WroteXMLnode(x, spaceStr + " ");
                }
            }
        }
    }
}

ソースコード(exXmlResolver.cs)

XXEと.NET Frameworkと全く同じなので、省略

戻る

XXE基本編へ戻る

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?