一直没有什么到目前为止所讨论的,什么可能最终成为了安全问题是,无论BULK INSERT
和OPENROWSET(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外部),它只会接收要从外部进程读取的文件中导入的数据。