为什么 BULK INSERT 被认为是危险的?

Jac*_*ton 22 sql-server permissions import bulk-insert

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

for (long i = 0; i < LONG_MAX; ++i)
    executeSQL("INSERT INTO table VALUES(...)");
Run Code Online (Sandbox Code Playgroud)

并且INSERT是一种常见的DML命令,任何人都基本写权限才能执行。

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

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

Sol*_*zky 21

鉴于可能存在与未知风险一样多的毫无根据的恐惧,我认为,如果不询问制定政策的人为什么担心,就很难真正说出为什么制定政策。

但是,我猜它可能与BULK INSERT/ SqlBulkCopy/ BCP /OPENROWSET(BULK ...)允许某人做的事情有关,即:

  1. 禁用约束 ( CHECK, DEFAULT,FOREIGN KEY我相信)
  2. 禁用触发器(如果有审计触发器,绕过它们可能会被认为是不可取的;有关此特定问题的更多解释,请参阅@DVKs 回答

以下文档中描述了各种选项:

我没有提到通过@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]);
    
    Run Code Online (Sandbox Code Playgroud)

    大多数人无法访问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-> 带有自定义解析数字数据、查找值的表管道


RDF*_*ozz 6

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

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

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

诚然,人们可以通过事务和简单的INSERT语句意外或故意地做到这一点。但是,按预期使用批量插入过程可能会导致这种效果。

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


DVK*_*DVK 6

这在较早的答案中有所提及(“...禁用触发器”),但并没有解释为什么从业务角度来看禁用是不可取的。

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

  1. 验证完整性约束(那些业务逻辑比通常在 DB 约束中使用的更复杂的)

  2. 更重要的是对数据进行审计,具体是将数据插入相应的审计表中(或更新主表中的审计字段)。

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

  • 首先,作为一个整体的审计不能再审计数据变化,因此无法履行其作为内部审计的主要职能。

  • 其次,缺少审计记录可能违反了公司受监管的审计要求(例如 SAS 70)——这可能会使您的公司因违反合同而承担责任。