Учитывая, что, вероятно, столько же необоснованных страхов, сколько и неизвестных рисков, я думаю, что трудно действительно сказать, почему существует политика, не спрашивая, кто ее создал, почему они обеспокоены.
Тем не менее, я предполагаю, что это, вероятно, связано с тем, что BULK INSERT
/ SqlBulkCopy
/ BCP / OPENROWSET(BULK ...)
позволяет кому-либо делать, а именно:
- отключить ограничения (
CHECK
, DEFAULT
иFOREIGN KEY
я считаю)
- отключить триггеры (если есть триггеры аудита, обход их, вероятно, будет сочтен нежелательным; более подробное описание этой конкретной проблемы см. в ответе @DVKs ).
Различные варианты описаны в следующей документации:
Я не упомянул проблему блокировки таблиц, отмеченную @RDFozz, поскольку она не является специфической для BULK INSERT
: любой может поставить таблицу TABLOCK / XLOCK или установить TRANSACTION ISOLATION LEVEL
в SERIALIZABLE
.
ОБНОВИТЬ
Я наткнулся на две дополнительные части информации, которые могут помочь сузить это:
Вопросы возможности для отключения триггеров, отключают ограничений и набора IDENTITY_INSERT ON
могут не быть подавляющей причиной , чтобы увидеть ADMINISTER BULK OPERATIONS
, ADMINISTER DATABASE BULK OPERATIONS
(начиная с SQL Server 2017), или bulkadmin
роли сервера в качестве угрозы. Причина в том, что для выполнения любой из этих трех только что упомянутых задач пользователю необходимо иметь ALTER TABLE
разрешения для этой таблицы или схемы, в которой эта таблица существует. Цепочка владения не распространяется на модификации DDL. Так что, если у пользователя нет ALTER TABLE
, то способность выполнять эти три вещи не является проблемой.
Что не обсуждается до сих пор, и что в конечном итоге может быть проблема безопасности является то , что оба и доступа к внешним ресурсам, вне SQL Server. При доступе к SQL Server через учетную запись Windows эта учетная запись Windows будет олицетворена (даже если вы переключите контекст безопасности с помощью ) для доступа к файловой системе. Это означает, что вы можете читать только те файлы, на которые у вас есть разрешение на чтение. В этом нет ничего плохого.BULK INSERT
OPENROWSET(BULK...
EXECUTE AS LOGIN='...'
НО, при доступе к SQL Server через имя входа SQL Server, внешний доступ осуществляется в контексте учетной записи службы SQL Server. Это означает, что кто-то с таким разрешением может читать файлы, которые в противном случае он не мог бы читать, и в папках, к которым у него не должно быть доступа.
Как минимум, если SQL Server был настроен для работы в качестве учетной записи, созданной только для SQL Server (предпочтительный метод), то такой пользователь мог читать только те файлы, к которым имеет доступ учетная запись «SQL Server». Хотя это ограниченная проблема, она по-прежнему позволяет читать файлы, такие как файлы журнала SQL Server (и я протестировал следующий пример, и он работает):
SELECT tmp.[Col1]
FROM OPENROWSET(BULK
N'C:\Program Files\Microsoft SQL Server\MSSQLxx.InstanceName\MSSQL\Log\ERRORLOG.1',
SINGLE_NCLOB) tmp([Col1]);
У большинства людей нет доступа к MSSQL \ Log папке , так что это способ обойти существующие ограничения безопасности.
И, если SQL Server работает как Local System
учетная запись, то я подозреваю, что масштаб проблемы только увеличивается, и что пользователь с таким разрешением сможет читать широкий спектр системных файлов.
И, вероятно, поэтому другие методы массового импорта - BCP и SqlBulkCopy
- не требуют bulkadmin
разрешения / роли: они инициируются вне SQL Server и будут обрабатывать разрешения файловой системы самостоятельно. В этих случаях SQL Server никогда не читает файл (или выходит за пределы SQL Server), он просто получает данные для импорта из файла, который читается внешним процессом.
Помимо возможных последствий, было сказано в вопросе:
В интересах приложения BULK INSERT намного эффективнее, быстрее, ..
Хорошо, продолжай ...
и избавляет программиста от необходимости разбирать файлы вне SQL.
Вау, Нелли. Давайте остановимся прямо здесь. T-SQL обычно не лучший выбор языков для разбора. Часто лучше выполнить синтаксический анализ, прежде чем вставлять данные в БД. Один из способов сделать это - использовать табличные параметры (TVP). Пожалуйста, смотрите мой ответ на другой вопрос (здесь, на DBA.StackExchange), который касается темы предварительного анализа и проверки наряду с эффективным массовым импортом указанных данных:
T-SQL: CSV-> конвейер таблицы с настраиваемыми проанализированными числовыми данными, значениями поиска