Это нормально для загрузки .net DLL в SQL Server как небезопасно? - PullRequest
1 голос
/ 21 апреля 2009

При создании хранимой процедуры SQL Server CLR я заметил, что не могу ссылаться на что-либо в инфраструктуре .net, как обычно. После некоторого осмотра я понял, что сборки должны быть сначала загружены в базу данных.

Поэтому я загрузил те, которые мне нужны, но из-за P / Invoke пришлось использовать набор разрешений UNSAFE. Теперь я могу ссылаться на них в своем коде хранимой процедуры, и все работает нормально.

Тем не менее, я немного обеспокоен необходимостью установить их в UNSAFE, когда я действительно не знаю, что они делают. Поэтому мой вопрос таков:

Можно ли загрузить .net framework как UNSAFE безо всяких действий? И как это может поставить под угрозу безопасность / надежность / масштабируемость сервера SQL (как предупреждает Microsoft)?

Большое спасибо.

Ответы [ 3 ]

2 голосов
/ 21 апреля 2009

Это может изменить реестр, перезапустить службы, перезагрузить сервер и т. Д. Ничего особенного ;-) Простая диаграмма с отличиями

См. Также этот вопрос (хотя ответов нет) SQL Server 2008: насколько безопасна защита от сбоев хранимая процедура CLR, которая загружает неуправляемые библиотеки

Конечно, что вы делаете, для чего требуется небезопасный доступ?

0 голосов
/ 18 ноября 2014

Этот вопрос относится только к загрузке сборок .Net Framework, которые не входят в набор Поддерживаемых библиотек .NET Framework , поэтому я сосредоточусь на контексте, который представляет собой поставляемые Microsoft DLL, а не случайную DLL.

Разница между сборками в списке «Поддерживаемые» и сборками, отсутствующими в списке, сводится к тому, что поддерживаемые сборки «были проверены на предмет соответствия стандартам надежности и безопасности для взаимодействия с SQL Server» (как на странице «Поддерживаемые библиотеки», ссылка на которую приведена выше). Основная проблема - это больше «надежность», чем «безопасность». Сборки в поддерживаемом списке были проверены на постоянное поведение , как ожидалось , без каких-либо ошибок или нечетных побочных эффектов. Функциональность была протестирована для работы с различными языками и сопоставлениями и т. Д.

Некоторые сборки .Net Framework, которых нет в списке поддерживаемых, могут быть загружены с PERMISSION_SET, установленным на SAFE. Это, однако, не гарантирует желаемого поведения. И некоторые могут быть загружены как UNSAFE без обязательного указания на наличие проблемы.

В качестве примера не гарантирующего поведения: я загрузил System.Drawing, чтобы выполнить некоторые простые манипуляции с изображениями. Я проверял манипуляции, когда изображение было предоставлено напрямую через byte[] / VARBINARY(MAX), а также когда оно было предоставлено путем файла и считывалось с диска. Все заработало как положено. Я отправил это кому-то в Германии, чьи Windows и SQL Server были установлены на «немецкий» в качестве языка. Он смог получить ожидаемые результаты при подаче изображения напрямую. Но когда он указывал путь к файлу, он не работал.

Что касается нежелательного поведения, SQL Server отобразит причины, по которым сборка не может быть загружена, как SAFE или EXTERNAL_ACCESS, когда вы попытаетесь это сделать. Например:

CREATE ASSEMBLY [System.Drawing]
AUTHORIZATION [dbo]
FROM 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll'
WITH PERMISSION_SET = SAFE;

Результаты:

Предупреждение. Сборка Microsoft .NET Framework 'system.drawing, версия = 4.0.0.0, культура = нейтральная, publickeytoken = b03f5f7f11d50a3a, processorarchitecture = msil.' Ваша регистрация не полностью протестирована в среде, размещенной на SQL Server, и не поддерживается. В будущем, если вы обновите или обслужите эту сборку или .NET Framework, ваша процедура интеграции CLR может перестать работать. Пожалуйста, обратитесь к электронной документации по SQL Server для получения более подробной информации.

Сообщение 6218, Уровень 16, Состояние 2, Строка 1
СОЗДАТЬ СБОРКУ для сборки «System.Drawing» не удалось, поскольку сборка «System.Drawing» не прошла проверку. Проверьте, являются ли указанные сборки современными и надежными (для external_access или unsafe) для выполнения в базе данных. Сообщения об ошибках CLR Verifier, если они появятся после этого сообщения

[: System.Drawing.BufferedGraphicsContext :: bFillColorTable] [mdToken = 0x600013c] [смещение 0x00000053] [найденный адрес байта] Ожидаемый числовой тип в стеке.

[: System.Drawing.BufferedGraphicsContext :: bFillColorTable] [mdToken = 0x600013c] [смещение 0x00000043] [найдено Native Int] [ожидаемый адрес байта] Неожиданный тип в стеке.

[: System.Drawing.BufferedGraphicsContext :: bFillColorTable] [mdToken = 0x600013c] [смещение 0x00000027] [найдено Native Int] [ожидаемый адрес байта] Неожиданный тип в стеке.

[: System.Drawing.Icon :: ToBitmap] [mdToken = 0x6000349] [смещение 0x00000084] [найден неуправляемый указатель] [ожидается неуправляемый указатель] Неожиданный тип в стеке.

[: System.Drawing.Icon :: ToBitmap] [mdToken = 0x6000349] [offset 0x000000E4] Неуправляемые указатели не поддаются проверке.

[: System.Drawing.Icon :: GetShort] [mdToken = 0x6000356] [offset 0x00000002] Неуправляемые указатели не поддаются проверке.
...

Если вы не собираетесь использовать какой-либо из этих методов или типов, то, скорее всего, у вас не возникнет никаких проблем. Просто невозможно отделить «безопасные» вещи от «небезопасных».

Еще один пример вины по ассоциации, но еще дальше удален:

CREATE ASSEMBLY [System.Web]
AUTHORIZATION [dbo]
FROM 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Web.dll'
WITH PERMISSION_SET = SAFE;

Результат:

Предупреждение. Сборка Microsoft .NET Framework 'system.web, версия = 4.0.0.0, культура = нейтральная, publickeytoken = b03f5f7f11d50a3a, processorarchitecture = x86.' Ваша регистрация не полностью протестирована в среде, размещенной на SQL Server, и не поддерживается. В будущем, если вы обновите или обслужите эту сборку или .NET Framework, ваша процедура интеграции CLR может перестать работать. Для получения более подробной информации обратитесь к электронной документации по SQL Server.

Предупреждение. Сборка Microsoft .NET Framework 'microsoft.build.framework, версия = 4.0.0.0, культура = нейтральная, publickeytoken = b03f5f7f11d50a3a, processorarchitecture = msil.' Ваша регистрация не полностью протестирована в среде, размещенной на SQL Server, и не поддерживается. В будущем, если вы обновите или обслужите эту сборку или .NET Framework, ваша процедура интеграции CLR может перестать работать. Для получения более подробной информации обратитесь к электронной документации по SQL Server.

Предупреждение. Сборка Microsoft .NET Framework 'system.xaml, версия = 4.0.0.0, культура = нейтральная, publickeytoken = b77a5c561934e089, processorarchitecture = msil.' Ваша регистрация не полностью протестирована в среде, размещенной на SQL Server, и не поддерживается. В будущем, если вы обновите или обслужите эту сборку или .NET Framework, ваша процедура интеграции CLR может перестать работать. Для получения более подробной информации обратитесь к электронной документации по SQL Server.

Сообщение 6212, Уровень 16, Состояние 1, Строка 1
Не удалось создать CREATE ASSEMBLY, поскольку метод «TypeDescriptorRefreshed» для типа «System.Windows.Markup.ValueSerializer» в безопасной сборке «System.Xaml» хранится в статическом поле. Хранение в статическом поле недопустимо в безопасных сборках.

Как видите, System.Web на самом деле вполне подходит для SAFE, но у него есть зависимые сборки, и они загружаются автоматически. Первая зависимая сборка, microsoft.build.framework, также не имеет проблем (по крайней мере, это не может быть проверено, хотя возможно, что что-то, что запрещено в SAFE, существует, но может быть перехвачено только во время выполнения). Но у второй зависимой сборки есть проблема, которую можно проверить при загрузке сборки: она «хранится в статическом поле». Это проблема для надежности больше, чем для безопасности, потому что классы создаются один раз (ну, для каждого домена приложения, то есть для каждой базы данных, для каждого владельца) и используются совместно через идентификаторы SPID (именно поэтому в SQLCLR доступны только статические методы) , Следовательно, статические переменные уровня класса технически обмениваются информацией между сеансами (то есть SPID), и это может очень легко вызвать неожиданное поведение. Но в то же время, если вы хотите использовать HtmlString.ToHtmlString(), вы, вероятно, не используете System.Xaml. Так почему бы просто не загрузить System.Web как SAFE и System.Xaml как UNSAFE? Возможно, потому что коду в SAFE сборках не разрешается вызывать код в UNSAFE сборках (по крайней мере, не в SQLCLR).

CONLUSION
Так нормально ли загружать сборки UNSAFE .Net Framework? Это действительно должно сводиться к тестированию. Множество тестов (и не только один поток на вашем компьютере разработчика, но real testing). Если все ведет себя как положено, то все будет в порядке. Но если что-то не работает должным образом, то это , а не ошибка, о которой можно сообщить в Microsoft, поскольку она уже была объявлена ​​неподдерживаемой.


EDIT:
И вот более официальный ответ на этот вопрос, в котором перечислены несколько ситуаций, в которых могут возникнуть проблемы : Политика поддержки для непроверенных сборок .NET Framework в среде SQL Server, размещенной в среде CLR

0 голосов
/ 30 января 2013

Когда вы используете ядро ​​базы данных SQL на сервере, на котором размещено много общедоступных веб-сайтов, о которых вы ничего не знаете как администратор сервера (или администратор баз данных, или кто-либо другой), вы должны ограничить их доступ и, черт возьми, это важно! Кроме того, если у вас есть администратор БД в ограниченной области, где данные имеют наибольшее значение в некоторых крупных компаниях, опять же, это самое важное.

С моей точки зрения, вы должны предоставить свое заявление так, как оно должно видеть, не более того. Если вам не нужно, например, просматривать реестр, почему вы хотите предоставить неограниченный доступ к сборке? Вы не представляете, насколько это может быть опасно, если кто-нибудь внедрит код вашего приложения и проникнет в базу данных (также с неограниченным доступом!).

Надеюсь, это поможет

...