Ответ 1
Как сборка CLR, созданная с помощью PERMISSION_SET = SAFE, может иметь доступ к внешним системным ресурсам, вызывать неуправляемый код и получать привилегии sysadmin?
Это связано с изменениями безопасности, внесенными в .NET Framework, начиная с версии 4.5 (я полагаю).
Документация MSDN по Основам безопасности Code Access гласит:
.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 Server (до SQL Server 2017) было разрешено продолжать использовать старую модель безопасности. Похоже, что начиная с SQL Server 2017 было принято решение больше не поддерживать старую модель безопасности.
Я подозреваю, что разрешение старой модели безопасности было:
предотвращение использования SQL Server (по крайней мере, связанных с CLR функциональностью/компонентами) на основе более новых версий .NET Framework и
отвечает за внезапное удаление SQLCLR как поддерживаемой функции из базы данных SQL Azure (поддержка была добавлена в конце 2014 года с запуском v12, но затем полностью удалена с 15 апреля 2016 года).
Так что да, это отстой. Это означает (по крайней мере, на данный момент), что нужно сначала создать сертификат или асимметричный ключ (который использовался для подписи любых сборок, которые должны быть загружены) в [master]
, чтобы затем создать логин и затем предоставить UNSAFE ASSEMBLY
к этому логину. Это та же последовательность событий, которую необходимо выполнить при загрузке сборок EXTERNAL_ACCESS
и UNSAFE
, но теперь, к сожалению, это необходимо сделать даже для сборок SAFE
.
В настоящее время не существует механизма, позволяющего обрабатывать это полностью переносимым способом (т.е. не полагаться на внешние файлы), и он не может быть обработан Visual Studio/SSDT без ручного вмешательства. Это уже было своего рода, но, по крайней мере, было возможно создать установку для обработки этого полностью переносимым способом (т.е. полностью в сценарии .sql): см. Лестница к SQLCLR Уровень 7: Разработка и Безопасность для деталей (это статья, которую я написал).
Можно создать сертификат из шестнадцатеричных байтов (то есть FROM BINARY = 0x...
), но это не работает с Visual Studio (которая опирается на MSBuild)/SSDT, поскольку для использования сертификата требуется использование signtool
, а MSBuild использует sn
.
Чтобы сделать это работоспособным, чтобы работал процесс публикации Visual Studio/MSBuild/SSDT (что, в свою очередь, означало бы, что любой сможет создать полностью автономный сценарий .sql, способный создавать асимметричный ключ, не полагаясь на внешний файл), необходимо улучшить команду CREATE ASYMMETRIC KEY
, чтобы она создавалась из двоичной строки. Я сделал это предложение в Microsoft Connect & ndash; Разрешить создание асимметричного ключа из двоичной шестнадцатеричной строки, как CREATE CERTIFICATE & ndash; поэтому, пожалуйста, поддержите это :-).
В качестве альтернативы (на данный момент, пока MS, как мы надеемся, не создадим лучший метод, такой как мои предложения по асимметричному ключу), вы можете попробовать любой из двух методов, которые я описал в следующих сообщениях в блоге (оба полностью работают с SSDT):
- SQLCLR против SQL Server 2017, часть 2: "строгая безопасность CLR" - решение 1
- SQLCLR против SQL Server 2017, часть 3: "строгая безопасность CLR" - решение 2
В качестве последнего средства вы можете рассмотреть следующий подход:
- ВРЕМЕННО установите базу данных
[master]
наTRUSTWORTHY ON
- Создать сборку в
[master]
- Создать асимметричный ключ из сборки
- Оставьте сборку
- установите для базы данных
[master]
значениеTRUSTWORTHY OFF
- Создать логин из асимметричного ключа
- Предоставьте
UNSAFE ASSEMBLY
этому логину
Обратите внимание, что здесь я не включил новую функцию "Надежная сборка". Причина, по которой он не был упомянут, заключается в том, что он имеет гораздо больше недостатков, чем преимуществ, не говоря уже о том, что он был совершенно ненужным, во-первых, с учетом того, что существующая функциональность уже справилась с ситуацией, которой должны были заниматься "Доверенные сборки". Подробную информацию об этом и демонстрацию правильного способа обработки существующих неподписанных сборок см. в разделе SQLCLR против SQL Server 2017, часть 4: "Доверенные сборки" - разочарование.