TypeInitializationException SQL Server CLR の実行が失敗する

この記事では、SQL Server CLR オブジェクトの実行が失敗し、System.TypeInitializationException 例外が返される問題を回避するのに役立ちます。

適用対象: SQL Server
元の KB 番号: 4576575

現象

重要

この記事では、セキュリティ設定を下げる方法や、コンピューターのセキュリティ機能をオフにする方法について説明します。 これらの変更を行って、特定の問題を回避できます。 これらの変更を行う前に、特定の環境でのこの回避策の実装に関連するリスクを評価することをお勧めします。 この回避策を実装する場合は、コンピューターの保護に役立つ適切な追加の手順を実行します。

CVE-2020-1147 で説明されている脆弱性を修正するために該当する.NET Framework更新プログラムをインストールした後、Xml を DataSet および DataTable セキュリティ ガイダンス オブジェクトに読み込む共通言語ランタイム (CLR) 統合を使用したデータベース オブジェクトのビルドの実行は失敗します。 これは、入れ子になった FileNotFoundException 例外がある System.TypeInitializationException 例外が原因で発生します。 この問題は、 System.Drawing アセンブリを読み込めなかったことを示します。

参照については、次の例を参照してください。

Msg 6522、Level 16、State 1、Procedure [your CLR object]、Line 0 [Batch Start Line 0] ユーザー定義ルーチンまたは集計 "your CLR オブジェクト" の実行中に.NET Framework エラーが発生しました。
System.TypeInitializationException: 'Scope' の型初期化子によって例外がスローされました。 >--- System.IO.FileNotFoundException: ファイルまたはアセンブリ 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=<Token>' またはその依存関係の 1 つを読み込めませんでした。 指定されたファイルが見つかりません。
System.TypeInitializationException:
at System.Data.TypeLimiter.Scope.IsTypeUnconditionallyAllowed(Type 型)
at System.Data.TypeLimiter.Scope.IsAllowedType(Type type)
at System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter) at System.Data.DataColumn.UpdateColumnType(Type type, StorageType typeCode)
System.Data.DataColumn..ctor(String columnName, Type dataType, String expr, MappingType type)
at System.Data.XSDSchema.HandleElementColumn(XmlSchemaElement elem, DataTable table, Boolean isBase)
at System.Data.XSDSchema.HandleParticle(XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
at System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, Boolean isNillable)
at System.Data.XSDSchema.InstantiateTable(XmlSchemaElement ノード, XmlSchemaComplexType typeNode, Boolean isRef)
at System.Data.XSDSchema.HandleTable(XmlSchemaElement ノード)
at System.Data.XSDSchema.HandleParticle(XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
at System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, Boolean isNillable)
at System.Data.XSDSchema.InstantiateTable(XmlSchemaElement ノード, XmlSchemaComplexType typeNode, Boolean isRef)
at System.Data.XSDSchema.HandleTable(XmlSchemaElement ノード)
at System.Data.XSDSchema.LoadSchema(XmlSchemaSet schemaSet, DataSet ds)
at System.Data.DataSet.InferSchema(XmlDocument xdoc, String[] excludedNamespaces, XmlReadMode モード)
System.Data.Data...

解決方法

この問題は、2020 年 7 月のSecurity-Only 更新.NET Frameworkの 2020 年 10 月 13 日の再発行で修正されました。

パッチの入手方法など、詳細については、「2020 年 7 月のセキュリティのみ更新の.NET Framework再発行」を参照してください。

回避策

警告

この回避策によって、コンピューターやネットワークが、悪意のあるユーザーやウイルスなどの悪質なソフトウェアからの攻撃を受けやすくなる場合があります。 この回避策はお勧めしませんが、この回避策を独自の裁量で実装できるように、この情報を提供しています。 この回避策は、自己の責任において使用してください。

信頼されていない XML データをオブジェクト DataSet または DataTable オブジェクトのインスタンスに逆シリアル化するアプリケーションの場合は、別の方法を使用してデータにアクセスすることをお勧めします。 信頼できる XML データのみを読み取るアプリケーションの場合は、次のいずれかの回避策を試すことができます。

注:

回避策 1 と 2 は、変更がローカルで行われるため、推奨されます。 回避策 3 はシステム全体です。

警告

これらの回避策により、XML を および オブジェクトのインスタンスに逆シリアル化するための型制限 DataSetDataTable 削除されます。 これにより、アプリケーションが信頼されていない入力を読み取ると、セキュリティ ホールが開く可能性があります。

  • 回避策 1: AppContext.SetSwitch を呼び出す

    SQL CLR オブジェクト コードの先頭を変更して 、Switch.System.Data.AllowArbitraryDataSetTypeInstantiation スイッチを true に設定 します。 これは、該当するすべての SQL CLR オブジェクトに対して行う必要があります。 次の例をご覧ください。

    SQL CLR オブジェクト コードの変更の例を示すスクリーンショット。

    詳細については、「 DataSet と DataTable のセキュリティ ガイダンス」を参照してください。

  • 回避策 2: 該当するインスタンスごとに Sqlservr.exe.config ファイルを作成または変更する

    この回避策は、インスタンス自体にのみ適用されます。

    重要

    更新プログラムまたはインスタンスのアップグレードによってこの変更が上書きされないことSQL Server保証することはできません。 インスタンスの更新またはアップグレード後に変更が保持されるかどうかを判断することをお勧めします。

    1. SQL Server既定および名前付きインスタンスのファイルの場所で、Sqlservr.exe.configファイルを見つけます。

      %ProgramFiles%\Microsoft SQL Server\<Instance_ID>.<Instance Name>\MSSQL\Binn\

    2. <runtime>ノード内で、入れ子になったノードの外側に、次の行を追加します。

      <AppContextSwitchOverrides value="Switch.System.Data. AllowArbitraryDataSetTypeInstantiation=true"/>
      
    3. ファイルを保存し、インスタンスを再起動します。

      SQL Server 2016 インスタンスの次の例を参照してください。

      SQL Server 2016 インスタンスの例を示すスクリーンショット。

  • 回避策 3: System.Drawing アセンブリを作成する

    グローバル アセンブリ キャッシュ (GAC) の DLL ファイルからSQL Serverで System.Drawing アセンブリを手動で作成し、DataSet.ReadXML または DataTable.ReadXML を使用するアセンブリを再作成します。 例:

    CREATE ASSEMBLY [Drawing] FROM 'C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll' WITH PERMISSION_SET = UNSAFE GO
    
  • 回避策 4: レジストリ サブキーを作成する

    重要

    この回避策の手順に慎重に従ってください。 レジストリを誤って変更すると、深刻な問題が発生することがあります。 変更する前に、問題の発生に備えて復元用にレジストリのバックアップを作成してください。

    この回避策は、サーバー上のすべての .NET アプリケーションに影響します。 したがって、他の回避策を使用できない場合は、最後の手段としてのみこのメソッドを使用する必要があります。

    1. レジストリ エディターを開きます。

    2. 次のサブキーを見つけます。

      KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext

    3. 次のように、REG_SZ値を作成します。

      名前 Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
      true
    4. すべてのSQL Serverインスタンスを再起動します。

      次の例をご覧ください。

      レジストリ エディターの AppContext レジストリ キーのスクリーンショット。

詳細

この問題は、.NET Framework XML コンテンツ マークアップの検証を修正するための最近の.NET Frameworkセキュリティ更新プログラムのアクションによって発生します。 SQL Serverまたは オブジェクトのDataSetDataTableインスタンスに XML を読み込まない CLR オブジェクトは影響を受けません。