web-dev-qa-db-ja.com

SQL Server 2017へのアップグレード後のエラーメッセージ10314、レベル16、状態11、SAFEアセンブリあり

私はSQL Server 2017より前のデータベースをSQL Server 2017に復元したり、SQL Server 2017にアップグレードしたりしています。このデータベースにはSQLCLRアセンブリがあります。アセンブリはSAFEとしてマークされています。これは、より高いレベルの権限を必要とすることは何も行わず、データベースでTRUSTWORTHYが無効/ OFFになっているためです。 SQLCLR関数とストアドプロシージャは、SQL Server 2017に移行する前に期待どおりに機能しましたが、これらのいずれかを実行しようとすると、次のエラーが発生します。

メッセージ10314、レベル16、状態11、サーバーXXXXXXXXXXX、行YYYYYY
アセンブリID ZZZZZを読み込もうとしたときに、Microsoft .NET Frameworkでエラーが発生しました。サーバーでリソースが不足しているか、アセンブリが信頼されていない可能性があります。クエリを再度実行するか、ドキュメントをチェックして、アセンブリの信頼の問題を解決する方法を確認してください。このエラーの詳細については:
System.IO.FileLoadException:ファイルまたはアセンブリ '{Assembly_name}、Version = 0.0.0.0、Culture = neutral、PublicKeyToken = null'またはその依存関係の1つを読み込めませんでした。セキュリティに関するエラーが発生しました。 (HRESULTからの例外:0x8013150A)

CLR統合/ SQLCLRがサーバー/インスタンスで有効になっていることを確認しました。

2
Solomon Rutzky

エラーは、SQL Server 2017の新しい_clr strict security_サーバーレベルの構成オプションの結果です。この新しいセキュリティ設定では、SAFEとマークされているものでも、作成またはロードできませんanyアセンブリ次の場合を除いて、実行のためにメモリに保存します。

  • TRUSTWORTHYのデータベースプロパティはONです(これは不要なセキュリティリスクであるため、行わないでください)andデータベース所有者であるログイン(つまり、_[dbo]_ユーザーが使用する同じSID) _UNSAFE Assembly_権限が必要です(所有者がsaの場合はすでに許可されている可能性がありますorsysadmin固定サーバーロールのメンバーorおそらく_CONTROL SERVER_権限)。
  • _clr strict security_のサーバーレベルの構成オプションが無効になっている/ _0_(不要なセキュリティリスクであるため、これを行わないでください)
  • アセンブリが署名されているand _UNSAFE Assembly_権限が付与された対応する署名ベースのログインがある(お願いこれを行う)
  • アセンブリのSHA-512ハッシュは「信頼できるアセンブリ」として登録されます(絶対にneverこれには多くの問題があるため、これは最初から必要ではなかったことは言うまでもありません)

この状況を修正するために必要なのは、次の手順のみです(これは難しくありませんand最高レベルのセキュリティを提供します)。

  1. アセンブリが存在するデータベースに証明書を作成します
  2. 証明書(公開キーと秘密キーの両方)をファイルにバックアップします。 (オプション)
  3. 証明書でアセンブリに署名します
  4. 秘密鍵を削除します(後でバックアップファイルから復元できます) (オプション)
  5. 署名されていない追加のデータベースごとに、SAFEアセンブリ:
    1. このサブステップをスキップして(ステップ6にスキップ)、ステップを完了し、プロセス全体を繰り返します(これにより、データベースごとに1つの証明書が必要になります)[〜#〜]または[〜# 〜]
    2. 次の手順を実行します(これにより、1つの証明書の合計が得られ、すべてのデータベースに使用されます):
      1. バックアップファイル(秘密キーを含む)から同じ証明書を作成します。
      2. 証明書でアセンブリに署名します
      3. 秘密鍵を削除します(後でバックアップファイルから復元できます)
  6. 証明書を_[master]_にコピー(公開鍵のみ!)
  7. 証明書からログインを作成
  8. 証明書ベースのログインに_UNSAFE Assembly_権限を付与します

これの簡単な例(オプションのバックアップと秘密鍵の削除を除く)は次のようになります。

_USE [{database_containing_unsigned_safe_Assembly}];

CREATE CERTIFICATE [{certificate_name}]
  ENCRYPTION BY PASSWORD = '{some password}'
  WITH SUBJECT = '{simple description}',
  EXPIRY_DATE = '2099-12-31';

ADD SIGNATURE
  TO Assembly::[{Assembly_name}]
  BY CERTIFICATE [{certificate_name}]
  WITH PASSWORD = '{some password}';

DECLARE @PublicKey VARBINARY(MAX),
        @SQL NVARCHAR(MAX);

SET @PublicKey = CERTENCODED(CERT_ID(N'{certificate_name}'));

SET @SQL = N'
CREATE CERTIFICATE [{certificate_name}]
  FROM BINARY = ' + CONVERT(NVARCHAR(MAX), @PublicKey, 1) + N';';
PRINT @SQL; -- DEBUG

EXEC [master].[sys].[sp_executesql] @SQL;

EXEC [master].[sys].[sp_executesql] N'
CREATE LOGIN [{login_name}]
  FROM CERTIFICATE [{certificate_name}];

GRANT UNSAFE Assembly TO [{login_name}]; -- REQUIRED!!!!
';
_

これの完全に機能する例(バックアップと秘密鍵の削除を除く)はPastebinにあります。
「信頼できるアセンブリ」を回避-デモ

なぜshould証明書を使用するのか、なぜnot "Trusted Assemblies"を使用するのかについての詳細な説明は、このブログ投稿で提供されています。
SQLCLRとSQL Server 2017、パート4:「信頼できるアセンブリ」–失望

また、セキュリティ上の問題を含む多数の問題と、それを使用することによる全体的な利点の欠如を考慮して、Microsoftに新しい「信頼されたアセンブリ」機能を削除するという私の要求をサポートすることを検討してください。

Trusted Assembliesは、証明書よりも問題がありますが機能が低下しています-削除してください

5
Solomon Rutzky