Риски безопасности или производительности при использовании SQL CLR [закрыто]

11

Существуют ли какие-либо особые риски безопасности или производительности при использовании CLR в SQL Server?

SQLBen
источник
Нет, код SQLCLR не может делать в базе данных больше ничего, чем эквивалентный модуль кода T-SQL, работающий в том же контексте безопасности. Неумышленное запрещение CLR также предотвращает развертывание SSISDB, что значительно повышает безопасность благодаря меньшему количеству учетных записей RDP, управлению файловой системой и меньшему количеству прав, наследованию резервных копий в планах обслуживания, полному шифрованию пакетов через TDE, не говоря уже о развертывании и обслуживании пакетов SSIS через раздел среды. SSISDB и отсутствие многих функций C # в SSIS, которые требуют CLR.
Брайан Свон
1
Я проголосовал, чтобы вновь открыть этот вопрос, потому что я считаю, что он имеет некоторое отношение к сообществу. Вопрос в его нынешнем виде является действительным, поскольку начальный уровень для администратора баз данных в настройках безопасности CLS довольно высок. Хорошо написанный ответ @SolomonRutzky обеспечивает хорошее введение в параметры безопасности CLR, которое не предоставлено на этом упрощенном уровне Microsoft.
Джон aka hot2use

Ответы:

10

Вопрос, как указал Ремус, слишком общий, чтобы получить ответ, так как ответ зависит от контекста того, какая функциональность будет использоваться и как она будет использоваться.

Относительно "безопасности":

Если вы спрашиваете о чем-либо, что можно сделать в сборке, помеченной значком PERMISSION_SET = SAFE, то я не смог найти никаких проблем, которые когда-либо могли бы найти. И SQLCLR "безопаснее", чем использование xp_cmdshellили замечательных (это был сарказм) процедур sp_OA*(или даже расширенных хранимых процедур, но, надеюсь, никто из них больше не создаст).

Если вы хотите получить представление о том, что «SAFE» означает в практическом плане, см. Эту статью: Лестница к SQLCLR Уровень 3: Безопасность (Общие и SAFE сборки) (требуется бесплатная регистрация).

Если вы спрашиваете обо всем, что можно сделать в сборке, помеченной значком PERMISSION_SET = EXTERNAL_ACCESS, то, безусловно, существуют риски, опять же, в зависимости от того, какая функциональность используется. Если вы пишете подпрограмму для чтения каталогов и имен файлов (то есть только для чтения), то это просто вопрос того, что следует видеть, а не видеть. Если вы пишете код, позволяющий удалить файл, риск возрастает. Но то, что можно сделать с этими внешними ресурсами, контролируется:

  • используете ли вы олицетворение или нет:
    • без олицетворения означает, что доступ к внешним ресурсам осуществляется через учетную запись «Вход в систему» ​​службы SQL Server. К чему бы ни имел доступ этот аккаунт, ваша функция SQLCLR сможет это сделать.
    • использование олицетворения означает, что имя входа в SQL Server, на котором выполняется эта функция, если это имя входа соответствует имени входа Windows, может делать все, что разрешено этому конкретному имени входа Windows. Если имя входа в SQL Server является именем входа SQL Server, то попытка использовать олицетворение приведет к ошибке.
  • Какие разрешения установлены на внешнем ресурсе. Для доступа к файловой системе это контролируется через ACL на дисках NTFS.

Если вы спрашиваете о чем-либо, что может быть сделано в сборке, отмеченной PERMISSION_SET = UNSAFEэто довольно открытый. Многие функциональные возможности считаются пригодными только для сборок UNSAFE, поскольку они представляют собой проблемы стабильности и / или согласованного поведения, а не безопасности или производительности. Например, в сборке UNSAFE возможно иметь доступную для записи статическую переменную. Обычно это не очень хорошая вещь, так как классы SQLCLR совместно используются всеми сеансами. Если вы намереваетесь обмениваться данными в памяти по всем сеансам и запланировали условия гонки (и провели много испытаний), то вы должны быть в порядке, ожидая такого поведения. Но если вы просто хотели, чтобы доступная для записи статическая переменная кэшировала значение для определенного сеанса, чтобы не приходилось искать его снова или вычислять снова, и не знали, что другие сеансы читают это значение и, возможно, перезаписывают его, ну, это было бы проблемой.

Но если вы беспокоитесь о том, что кто-то пишет в Реестр, но при этом у вас нет кода, который действительно пишет в Реестр, то вам, вероятно, не нужно беспокоиться об этом ;-).

Если вы хотели бы получить представление о том, как EXTERNAL_ACCESS и UNSAFE работают в практическом плане, и разницу между настройкой TRUSTWORTHY ON(не желательно) и использованием асимметричного входа на основе ключа или сертификата, см. Эту статью: Лестница к SQLCLR уровня 4: Безопасность (ВНЕШНИЕ и БЕЗОПАСНЫЕ сборки) (требуется бесплатная регистрация).

Относительно «Производительности»:

Это все зависит от того, что вы пытаетесь сделать и как вы это делаете. Есть некоторые вещи, которые намного быстрее в SQLCLR, и некоторые вещи, которые медленнее. Но, как и в случае с T-SQL, можно взять несколько простых и / или эффективных задач и сделать их сложными и / или неэффективными из-за неправильного выполнения действий. Но использование SQL CLR по своей природе не медленнее.

Соломон Руцкий
источник
6

SQLCLR сборка может быть установлена с тремя уровнями безопасности доступа: SAFE | EXTERNAL_ACCESS | UNSAFE. Это в полной мере документированы см CREATE ASSEMBLYи Проектирование Ассамблей :

Управление безопасностью сборки
Вы можете контролировать, насколько сборка может обращаться к ресурсам, защищенным .NET Code Access Security, когда она запускает управляемый код. Это можно сделать, указав один из трех наборов разрешений при создании или изменении сборки: SAFE, EXTERNAL_ACCESS или UNSAFE.

SAFE
SAFE - это набор разрешений по умолчанию, и он является наиболее строгим. Код, запускаемый сборкой с разрешениями SAFE, не может получить доступ к внешним системным ресурсам, таким как файлы, сеть, переменные среды или реестр. БЕЗОПАСНЫЙ код может обращаться к данным из локальных баз данных SQL Server или выполнять вычисления и бизнес-логику, которые не требуют доступа к ресурсам за пределами локальных баз данных.
Большинство сборок выполняют задачи вычислений и управления данными, не имея доступа к ресурсам вне SQL Server. Поэтому мы рекомендуем SAFE в качестве набора разрешений на сборку.

EXTERNAL_ACCESS
EXTERNAL_ACCESS позволяет сборкам получать доступ к определенным внешним системным ресурсам, таким как файлы, сети, веб-службы, переменные среды и реестр. Только учетные записи SQL Server с разрешениями EXTERNAL ACCESS могут создавать сборки EXTERNAL_ACCESS. Сборки SAFE и EXTERNAL_ACCESS могут содержать только код, который может быть проверен на безопасность. Это означает, что эти сборки могут получать доступ к классам только через четко определенные точки входа, действительные для определения типа. Следовательно, они не могут произвольно обращаться к буферам памяти, не принадлежащим коду. Кроме того, они не могут выполнять операции, которые могут отрицательно повлиять на надежность процесса SQL Server.

UNSAFE
UNSAFE предоставляет сборкам неограниченный доступ к ресурсам как внутри, так и за пределами SQL Server. Код, который выполняется из сборки UNSAFE, может вызывать неуправляемый код. Кроме того, указание UNSAFE позволяет коду в сборке выполнять операции, которые считаются небезопасными для верификатора CLR. Эти операции могут потенциально обращаться к буферам памяти в пространстве процессов SQL Server неконтролируемым образом. UNSAFE-сборки также могут потенциально подорвать систему безопасности SQL Server или общеязыковой среды выполнения. Разрешения UNSAFE должны предоставляться только опытным разработчикам или администраторам только для сборок с высоким уровнем доверия. Только члены предопределенной роли сервера sysadmin могут создавать сборки UNSAFE.

Существуют дополнительные ограничения на допустимые атрибуты CLR, и поддерживается только подмножество сборок .Net Framework. Опять же, обратитесь к связанной документации.

Что касается производительности, самое важное - помнить, что SQL Server - это многозадачная среда для совместной работы, а CLR - нет. Код SQLCLR должен вызываться Thread.BeginThreadAffinity()каждый раз, когда он загружает ЦП в течение любой продолжительности (включая блокировку). Адам Мачаник имеет отличную презентацию на эту тему, смотрите Data, Faster: Microsoft SQL Server Performance Techniques с SQLCLR .

Тема обширная и вопрос расплывчатый. SQLCLR может выполнять некоторые уникальные задачи, с которыми не может сравниться ни одна другая функция. А SQLCLR - это еще одно оружие в арсенале SQL Server, с которым вы можете застрелиться, с производительностью или безопасностью. Прочитайте документацию.

Ремус Русану
источник
Спасибо за это Ремус. Я знаю, что вопрос расплывчатый, но есть ли какие-либо проблемы безопасности по этому поводу? спасибо
SQLBen