为什么批量插入被认为是危险的?


21

我想了解为什么一般的网络安全团队(我处理过的一个以上的组织BULK INSERT)对于向应用程序和数据库程序员授予(例如TSQL)权限是一成不变的?我无法相信“填补磁盘滥用”的借口,除非我遗漏了一些东西,因为最终结果与执行类似操作的应用程序没有什么不同:

for (long i = 0; i < LONG_MAX; ++i)
    executeSQL("INSERT INTO table VALUES(...)");

并且INSERT是具有基本写权限的任何人都可以执行的常见DML命令。

为了使应用程序受益,BULK INSERT它效率更高,速度更快,并且使程序员无需解析SQL之外的文件。

编辑:我最初在信息安全站点上问这个问题是有原因的-不是DBA反对使用BULK INSERT,而是“信息保证”(IA简称-网络安全人员)正在迫使该问题。我让这个问题再讲一两天,但是如果批量操作确实确实绕过了约束或触发器,我可以看到这是一个问题。

Answers:


19

鉴于可能存在着无根据的恐惧和未知的风险,我想很难说出为什么制定一项政策而又不问制定该政策的人为何担心。

不过,我猜想,这可能有事情做什么BULK INSERT/ SqlBulkCopy/ BCP / OPENROWSET(BULK ...)让别人去做,即:

  1. 禁用约束(CHECKDEFAULT和,FOREIGN KEY我相信)
  2. 禁用触发器(如果有适当的审计触发器,则绕过它们可能会被认为是不可取的;有关此特定问题的更多说明,请参见@DVKs answer

以下文档中介绍了各种选项:

我没有提到@RDFozz指出的表锁定问题,因为这并不特定于BULK INSERT:任何人都可以表TABLOCK / XLOCK或将其设置TRANSACTION ISOLATION LEVELSERIALIZABLE

更新

我遇到了另外两个信息,可能有助于缩小范围:

  1. 能够禁用触发器,禁用约束和设置的问题IDENTITY_INSERT ON可能不是ADMINISTER BULK OPERATIONSADMINISTER DATABASE BULK OPERATIONS(从SQL Server 2017开始)或bulkadmin服务器角色视为威胁的压倒性原因。原因是,为了执行上述三件事中的任何一项,用户需要ALTER TABLE对该表或该表所在的模式具有权限。所有权链接不涉及DDL修改。因此,如果用户没有ALTER TABLE,那么做这三件事的能力就不成问题了。

  2. 一直没有什么到目前为止所讨论的,什么可能最终成为安全问题是,无论BULK INSERTOPENROWSET(BULK...访问外部资源,SQL Server之外。通过Windows登录名访问SQL Server时,将模拟该Windows帐户(即使您使用切换了安全上下文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->具有自定义解析数字数据,查找值的表管道


复制到位后,对于批量插入还有其他注意事项。
mustaccio

6

在较早的答案(“ ... 禁用触发器 ”)中已经提到了这种说法,但是没有解释为什么从业务角度来看禁用是不希望的。

在许多企业中,主表上的触发器用于:

  1. 验证完整性约束(业务逻辑比数据库约束中通常使用的约束更复杂)

  2. 更重要的是,审核数据,特别是将数据插入相应的审核表(或更新主表中的审核字段)。

前者的问题很明显(您的应用程序容易插入对下游处理有负面影响的不良数据)。至于后者,如果禁用了触发器,则您没有任何审核信息,从审核的角度来看,这带来了两个问题:

  • 首先,作为一个整体的审核不能再审核数据更改,因此无法执行其作为内部审核的主要功能。

  • 其次,缺少审核记录可能违反了公司所遵循的审核要求(例如SAS 70),这可能会使您的公司对违反合同承担责任。


嗨,您好。我不同意您对此处不希望出现的情况的描述,我也非常感谢您提供的详细信息,但仅作记录,我确实在回答中指出,如果存在审计触发器,则禁用触发器是不希望的。是的,这不是详细的解释,但是说“没有解释”并不能完全准确。也许最好说它太简单了,或者没有提供足够的关于审计触发器的解释,也没有提及验证(提及+1以及总体上的其他细节)。只是一个想法。
所罗门·鲁兹基

@SolomonRutzky-我特别指出答案“不解释为什么 ”,这就是一个问题:技术细节通常无关紧要,特别是与正在与IA进行基于业务的讨论的OP尤其如此。换句话说,如果他们说“哦,审计触发器可能被禁用”,IA将询问“ 达达对我们意味着什么?” -他们通常不是DBA或开发人员。
DVK

好。我想我刚读完第一句话就是说“提到禁用触发器的其他答案是不可取的,但没有解释原因”。是的,我通常同意您关于正确定义问题的需要,我假设(可能并不总是最好的政策;-) OP理解了禁用审核机制的含义。如果我不正确,那么很高兴您在此处提供了该信息。因此,我刚刚更新了我的答案,为此目的链接到此:)
所罗门·鲁兹基

6

另一种可能性是运行BULK INSERT操作的影响。

通常,这种事情将在可能的情况下在非工作时间运行,以免干扰正常活动。批量插入可能会将表锁定几个小时,从而防止发生其他插入(以及选择,更新或删除)。

或者,从安全角度来看,它可以产生与DoS攻击非常相似的结果。

诚然,可以通过事务和简单的INSERT语句意外地或故意地执行此操作。但是,按预期使用批量插入过程可能会导致这种效果。

通常,我希望DBA参与组织下班时间活动,因为他们还需要确保备份和其他计划的工作全部完成。如果人们在没有充分考虑此类活动的情况下安排此类事情,您可能会看到备份失败-由于多种原因,这可能是一个问题。


2

原因之一可能在于明确记录操作。如果每个操作都对应于日志文件中的一个条目,那么在没有任何其他参考的情况下查看导致问题的内容是相当琐碎的。如果您的日志文件显示“从external.file插入”,而没有external.file,则您将一无所获。

当然,您可以修改日志记录的工作方式,但是作为起点,即使在日志记录中将所有操作强制为原子操作也不是一个糟糕的主意。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.