Je voudrais comprendre pourquoi les équipes de cybersécurité en général (plus d'une organisation avec laquelle j'ai eu affaire) sont décidées à ne pas accorder BULK INSERT
(par exemple TSQL) sur les applications et les programmeurs de bases de données? Je ne peux pas croire l'excuse "remplir l'abus de disque", sauf si je manque quelque chose, car le résultat final n'est pas différent d'une application faisant quelque chose comme:
for (long i = 0; i < LONG_MAX; ++i)
executeSQL("INSERT INTO table VALUES(...)");
et INSERT
est une commande DML courante que toute personne disposant d'une autorisation d'écriture de base peut exécuter.
Pour le bénéfice d'une application, BULK INSERT
est beaucoup plus efficace, plus rapide et soulage le programmeur de la nécessité d'analyser des fichiers en dehors de SQL.
Edit: J'ai initialement posé cette question sur le site de sécurité de l'information pour une raison - ce ne sont pas les administrateurs de base de données qui sont contre l'utilisation de BULK INSERT, c'est l '"assurance de l'information" (IA pour faire court - les gens de la cybersécurité) qui forcent le problème. Je vais laisser cette question mijoter encore un jour ou deux, mais si l'opération en bloc contourne effectivement les contraintes ou les déclencheurs, je peux voir que c'est un problème.
Étant donné qu'il y a probablement autant de craintes infondées que de risques inconnus, je pense qu'il est difficile de vraiment dire pourquoi une politique est en place sans demander à la personne qui l'a créée pourquoi elle est concernée.
Cependant, je suppose que cela a probablement quelque chose à voir avec ce que BULK INSERT
/SqlBulkCopy
/ [~ # ~] bcp [~ # ~] /OPENROWSET(BULK ...)
permet à quelqu'un de faire, à savoir:
CHECK
, DEFAULT
et FOREIGN KEY
je crois)Les différentes options sont décrites dans la documentation suivante:
Je n'ai pas mentionné le problème de verrouillage de table noté par @RDFozz car cela n'est pas spécifique à BULK INSERT
: N'importe qui peut déposer un TABLOCK/XLOCK ou définir le TRANSACTION ISOLATION LEVEL
Sur SERIALIZABLE
.
[~ # ~] mise à jour [~ # ~]
Je suis tombé sur deux informations supplémentaires qui pourraient aider à affiner cela:
Les problèmes de pouvoir désactiver les déclencheurs, désactiver les contraintes et définir IDENTITY_INSERT ON
Pourraient pas être une raison écrasante de voir ADMINISTER BULK OPERATIONS
, ADMINISTER DATABASE BULK OPERATIONS
(à partir de SQL Server 2017), ou le rôle de serveur bulkadmin
en tant que menace. La raison en est que pour effectuer l'une des trois choses mentionnées ci-dessus, l'utilisateur doit disposer des autorisations ALTER TABLE
Sur cette table ou sur le schéma dans lequel la table existe. Le chaînage de propriété ne couvre pas les modifications DDL. Donc, si l'utilisateur n'a pas ALTER TABLE
, La possibilité de faire ces trois choses n'est pas un problème.
Ce qui n'a pas été discuté jusqu'à présent, et ce qui pourrait finalement être le problème de sécurité, c'est que BULK INSERT
Et OPENROWSET(BULK...
Accèdent à des ressources externes, en dehors de SQL Server . Lorsque vous accédez à SQL Server via une connexion Windows, ce compte Windows sera emprunté (même si vous changez le contexte de sécurité à l'aide de EXECUTE AS LOGIN='...'
) Pour effectuer l'accès au système de fichiers. Cela signifie que vous ne pouvez lire que les fichiers qui vous ont été autorisés à lire. Aucun problème avec ça.
MAIS, lors de l'accès à SQL Server via une connexion SQL Server, puis l'accès externe se fait dans le contexte de la Compte de service SQL Server. Cela signifie qu'une personne disposant de cette autorisation peut lire des fichiers qu'elle ne devrait pas pouvoir lire autrement et dans des dossiers auxquels elle ne devrait pas avoir accès.
Au minimum, si SQL Server a été configuré pour s'exécuter en tant que compte créé uniquement pour SQL Server (la méthode préférée), un tel utilisateur ne peut lire que les fichiers auxquels le compte "SQL Server" a accès. Bien que ce soit un problème limité, il permet toujours de lire des fichiers tels que les fichiers journaux de SQL Server (et j'ai testé l'exemple suivant et cela fonctionne):
SELECT tmp.[Col1]
FROM OPENROWSET(BULK
N'C:\Program Files\Microsoft SQL Server\MSSQLxx.InstanceName\MSSQL\Log\ERRORLOG.1',
SINGLE_NCLOB) tmp([Col1]);
La plupart des gens n'auront pas accès au dossier MSSQL\Log , ce serait donc un moyen de contourner les restrictions de sécurité existantes.
Et, si SQL Server s'exécute en tant que compte Local System
, Je soupçonne que l'étendue du problème ne fait qu'augmenter et qu'un utilisateur disposant de cette autorisation pourrait lire un large éventail de fichiers liés au système.
ET, c'est probablement la raison pour laquelle les autres méthodes d'importation en masse - [~ # ~] bcp [~ # ~] et SqlBulkCopy
- ne nécessitent pas l'autorisation/le rôle bulkadmin
: ils sont lancés en dehors de SQL Server et gèrent eux-mêmes les autorisations du système de fichiers. Dans ces cas, SQL Server ne lit jamais le fichier (ou atteint en dehors de SQL Server), il reçoit simplement les données à importer du fichier lu par le processus externe.
Outre les implications possibles, il a été dit dans la question:
Pour le bénéfice d'une application, BULK INSERT est beaucoup plus efficace, plus rapide, ..
OK continue...
et soulage le programmeur de la nécessité d'analyser des fichiers en dehors de SQL.
Whoa Nelly. Arrêtons ici. T-SQL n'est généralement pas le meilleur choix de langues pour l'analyse. Il est souvent préférable d'effectuer l'analyse avant d'insérer des éléments dans la base de données. Pour ce faire, vous pouvez utiliser les paramètres table (TVP). Veuillez consulter ma réponse à une autre question (ici sur DBA.StackExchange) qui traite du sujet de la pré-analyse et de la validation ainsi que de l'importation en masse efficace desdites données:
Une autre possibilité est l'impact de l'exécution d'un BULK INSERT
opération.
Normalement, ce genre de choses serait exécuté en dehors des heures de travail lorsque cela est possible, afin de ne pas interférer avec l'activité normale. Une insertion en bloc peut verrouiller une table pendant des heures, empêchant d'autres insertions de se produire (ainsi que la sélection, les mises à jour ou les suppressions).
Ou, du point de vue de la sécurité, cela peut produire des résultats très similaires à une attaque DoS.
Certes, on peut le faire accidentellement ou délibérément avec des transactions et de simples instructions INSERT
. Cependant, l'utilisation d'un processus d'insertion en bloc comme prév peut provoquer cet effet.
En règle générale, je m'attends à ce qu'un administrateur de base de données soit impliqué dans l'organisation des activités en dehors des heures d'ouverture, car il doit également s'assurer que les sauvegardes et autres tâches planifiées sont terminées. Si les gens planifiaient ce genre de choses sans suffisamment de considération pour de telles activités, vous pourriez voir les sauvegardes échouer - ce qui peut être un problème pour un certain nombre de raisons.
C'était une sorte de référence à une réponse précédente ("... désactiver les déclencheurs "), mais n'explique pas ( pourquoi la désactivation ne serait pas souhaitable du point de vue commercial.
Dans de nombreuses entreprises, les déclencheurs sur la table principale sont utilisés pour:
Valider les contraintes d'intégrité (celles dont la logique métier est plus compliquée que celle habituellement utilisée dans les contraintes de base de données)
Plus important encore, pour auditer les données, en particulier pour insérer des données dans table d'audit (ou mettre à jour les champs d'audit dans la table principale).
Il est assez évident quels sont les problèmes avec les premiers (votre application est susceptible d'insérer de mauvaises données qui ont des effets négatifs sur le traitement en aval). En ce qui concerne ce dernier, si un déclencheur est désactivé, vous ne disposez d'aucune information d'audit, ce qui pose deux problèmes du point de vue de l'audit:
Tout d'abord, l'audit en tant que groupe ne peut plus auditer les modifications des données et ne peut donc pas remplir sa fonction principale d'audit interne.
Deuxièmement, le manque de dossiers d'audit peut être une violation des exigences d'audit dont une entreprise est régie (par exemple SAS 70) - ce qui peut rendre votre entreprise responsable de la violation des contrats.
Une des raisons peut être due à la clarté de la consignation des actions. Si chaque action correspond à une entrée dans un fichier journal, il est assez trivial de voir quelque chose qui a causé un problème sans aucune référence supplémentaire. Si votre fichier journal indique "INSERT FROM external.file", sans external.file, vous ne pouvez rien dire de plus.
Bien sûr, vous pouvez modifier le fonctionnement de la journalisation, mais comme point de départ, forcer chaque action à être atomique même dans la journalisation n'est pas une idée terrible.