Строгая безопасность среды CLR на SQL Server 2017

MSDN on в этой статье говорит:

CLR использует безопасность доступа к коду (CAS) в .NET Framework, которая отсутствует дольше поддерживается в качестве границы безопасности. Создал сборку CLR с PERMISSION_SET = SAFE может иметь доступ к ресурсам внешней системы, вызовите неуправляемый код и получите привилегии sysadmin. Начиная с SQL Server 2017, параметр sp_configure под названием clr строгая безопасность введено для повышения безопасности сборок CLR. среда CLR строгий безопасность включена по умолчанию и обрабатывает SAFE и EXTERNAL_ACCESS сборки, как будто они были помечены как небезопасные. Среда CLR строгой безопасности опция может быть отключена для обеспечения обратной совместимости, но это не рекомендуемый. Корпорация Майкрософт рекомендует, чтобы все сборки были подписаны сертификат или асимметричный ключ с соответствующим логином, который был предоставлено небезопасное разрешение на сборку в базе данных master.

как можно создать сборку CLR с помощью PERMISSION_SET = SAFE может иметь доступ к внешним системным ресурсам, вызывать неуправляемый код и получать привилегии sysadmin?

почему CAS больше не поддерживается в качестве границы безопасности?

Как я понимаю, сборки CLR больше не могут быть безопасными, что очень неудачно.

2 ответов


как сборка CLR, созданная с PERMISSION_SET = SAFE, может иметь доступ к внешним системным ресурсам, вызывать неуправляемый код и получать привилегии sysadmin?

это связано с изменениями безопасности, внесенными в .NET Framework, начиная с версии 4.5 (я считаю).

документация MSDN для Основы Безопасности Доступа К Коду гласит:

.NET Framework предоставляет механизм для принудительного выполнения различных уровней доверия к различным кодам, запущенным в одном приложении под названием Code Access Security (CAS). Безопасность доступа к коду в .NET Framework не должна использоваться в качестве механизма обеспечения границ безопасности на основе происхождения кода или других аспектов идентификации. Мы обновляем наше руководство, чтобы отразить, что безопасность доступа к коду и прозрачный для безопасности код не будут поддерживаться в качестве границы безопасности с частично доверенным кодом, особенно кодом неизвестного происхождения. Мы не рекомендуем загрузка и выполнение кода неизвестного происхождения без применения альтернативных мер безопасности.

а затем указывает на страницу для изменения безопасности в .NET Framework в которой говорится:

наиболее важным изменением безопасности в .NET Framework 4.5 является строгое именование.

который затем указывает на документацию для Улучшенное Сильное Именование в которой говорится:

ключи строгого имени состоят из ключа подписи и ключа идентификации. Сборка подписывается ключом подписи и идентифицируется ключом идентификации. До .NET Framework 4.5 эти два ключа были идентичны. Начиная с .NET Framework 4.5, ключ идентификации остается таким же, как и в более ранних версиях .NET Framework, но ключ подписи усиливается с помощью более сильного хэш-алгоритма. Кроме того, ключ подписи подписывается ключом удостоверения для создания встречная подпись.

кроме того, документация для Безопасные Рекомендации По Кодированию гласит:

безопасность доступа к коду и безопасность-прозрачный код не будет поддерживаться в качестве границы безопасности с частично доверенным кодом. Мы не рекомендуем загружать и выполнять код неизвестного происхождения без применения альтернативных мер безопасности...

Итак, модель безопасности для .NET изменилась много лет назад, но SQL Серверу (до SQL Server 2017) разрешено продолжать использовать старую модель безопасности. Похоже, что, начиная с SQL Server 2017, было принято решение больше не поддерживать старую модель безопасности.

я подозреваю, что разрешение старой модели безопасности было:

  • предотвращение SQL Server (по крайней мере, функции / компоненты, связанные с CLR) на основе более новых версий .NET Framework и

  • ответственность за резкое удаление SQLCLR как поддерживаемой функции из базы данных SQL Azure (поддержка была добавлена в конце 2014 года с запуском v12, но затем полностью удалена с 15 апреля 2016 года).


так что, да, это отстой. Это означает (по крайней мере, на данный момент), что нужно первый создайте сертификат или асимметричный ключ (который использовался для подписи любых загружаемых сборок) в [master] создать логин и грант!--1--> к этому логину. Это та же последовательность событий, что и при загрузке EXTERNAL_ACCESS и UNSAFE сборки, но теперь, к сожалению, нужно сделать даже для SAFE сборки.

в настоящее время нет механизма для обработки этого полностью переносимым способом (т. е. не полагаться на внешние файлы) и не может быть обработан Visual Studio / SSDT без ручного вмешательства. Это уже было так, но, по крайней мере, можно было создать настройку для обработайте это полностью портативным способом (т. е. полностью содержащимся в a .SQL-скрипт): посмотрите, пожалуйста лестница на уровень SQLCLR 7: разработка и безопасность подробности (это статья, которую я написал).

можно создать сертификат из шестнадцатеричных байтов (т. е. FROM BINARY = 0x...), но это не работает с Visual Studio (которая полагается на MSBuild) / SSDT, так как использование сертификата требует использования signtool и MSBuild использует sn.

для это должно быть сделано работоспособным, чтобы процесс публикации Visual Studio / MSBuild / SSDT работал (что, в свою очередь, означало бы, что любой сможет создать полностью автономный .SQL-скрипт, способный создать асимметричный ключ, не полагаясь на внешний файл),CREATE ASYMMETRIC KEY команда должна быть расширена, чтобы быть создана из двоичной строки. Я сделал это предложение на Microsoft Connect -разрешить создание асимметричного ключа из строки двоичных шестнадцатеричных байтов так же, как СОЗДАТЬ СЕРТИФИКАТ – так, Пожалуйста, поддержите его :-).

альтернативно (на данный момент, пока MS, надеюсь, не создаст лучший метод, такой как мои асимметричные ключевые предложения), вы можете попробовать любой из двух методов, которые я описываю в следующих сообщениях в блоге (оба полностью работают с SSDT):

как последние курорт, вы можете рассмотреть следующий подход:

  1. временно установить

Я столкнулся с этим на днях, и, кажется, это не так плохо, как кажется (кроме того, что вы больше не можете просто создать безопасную сборку, но нужно подписать ее и т. д., или использовать надежные).

в моих тестах:

  • Я создал сборку, которая имела "безопасный" метод, а также " небезопасный" (это задача).
  • Я создал сборку как безопасную (после того, как построил и подписал ее так далее.)
  • Я создал функции оболочки T-SQL вокруг моего два метода.
  • при выполнении функции "SAFE"все работало.
  • при выполнении "UNSAFE" я получил исключение HostProtectionException.

Это для меня означает, что все еще есть некоторые элементы управления тем, что выполняется. За этим я последовал:--1-->

  • повторное создание сборки с помощью PERMISSION_SET = UNSAFE
  • воссоздал функции
  • теперь, когда я выполнил небезопасную функцию, все работали как ожидаемый.

поэтому я не уверен, что утверждение в документации "clr strict security" на 100% правильно.

Я написал блог-пост о своем опыте, и вы можете найти его здесь, Если хотите проверить его самостоятельно: http://www.nielsberglund.com/2017/07/02/sql-server-2017-sqlclr-and-permissions/

Нильс