什么是Oracle DBMS_ASSERT的Sql Server等价物?

时间:2009-11-11 22:05:43

标签: sql sql-server oracle sql-injection

DBMS_ASSERT 是防止Oracle中SQL注入攻击的关键之一。我尝试了一个粗略的搜索...是否有任何SQL Server 2005/2008等效于此功能?

我正在寻找一个特定的实现,它具有DBMS_ASSERT的所有相应Oracle包成员的对应物。

  • NOOP
  • SIMPLE_SQL_NAME
  • QUALIFIED_SQL_NAME
  • SCHEMA_NAME

我知道防止注射的最佳做法...绑定变量......就是其中之一 但是,在这个问题中,我特意寻找一种清理输入的好方法......在没有使用绑定变量的情况下。

您是否有任何具体的实施方案? 是否有一个实际上是Oracle软件包的SQL Server端口的库?

6 个答案:

答案 0 :(得分:2)

不要通过构建字符串并执行它们来进行动态查询。

使用sp_executesql并将参数作为参数传递。

你会发现sql注入不再存在。

编辑:对不起,我匆忙写了错误的命令。它不是sp_execute,它是sp_executesql;它需要一个字符串和一组参数:所有参数的编码和转义都是由SQL Server完成的。

EDIT2 sp_executesql statement explaination

答案 1 :(得分:2)

我最接近的是TSQLAssert for TSQLMacro,但它只支持TSQL存储过程。它是免费的。

  

TSQLAssert是一个断言框架   建立在TSQLMacro之上。它是   旨在提供调试时间   断言失败类似于   C ++等语言中的断言 -   带有额外的日志记录组件   没有找到那些语言。   TSQLAssert只能在其中使用   存储过程和触发器 -   不幸的是,用户定义的功能   并且观点不支持许多   允许它工作的关键字。

答案 2 :(得分:1)

没有神奇的“防止注射”命令。该方法是以下的组合:

  1. 使用参数化查询确保类型安全
  2. 在将输入传递到数据库层之前清理输入
  3. 当你不能做1.和2.时,在盲目执行动态SQL之前,在所有输入和其他清理方法中替换'with''。

答案 3 :(得分:1)

因此,SQL SERVER中没有DBMS_ASSERT。

然而,通过这个链接增强了Aaron Bertrand的答案 SQL Injection

答案 4 :(得分:1)

唯一可能的选项是QUOTENAME,它用于转义对象名称(因此可能是SIMPLE_SQL_NAMEENQUOTE_NAME以及其他可能的等价物。所以表名(提供)它们不具有所有者或数据库的资格)并且列名可以被转义。

没有完全限定对象的机制(例如,将表'bob'转换为'database.owner.bob'),所以你必须手动将它们放在一起,可选择使用QUOTENAME逃避价值观,例如:

QUOTENAME(@database) + '.' + QUOTENAME(@owner) + '.' + QUOTENAME(@tableName)

如果对象在现有数据库中,那么您可以使用DB_NAME(),并假设所有者将作为变量传入:

DB_NAME() + '.' + QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)

以一种非常复杂的方式,你也可以让主人出去:

USER_NAME(OBJECTPROPERTY(OBJECT_ID(@tablename), 'ownerid')))

是的,我发现所有这些都可能被视为解决方法,但它们是选项。

但是,对于转义值,您实际上是独立的:没有内置的SQL Server等效项,因此将是所有手动字符串操作。您可能可以创建一个UDF来执行此操作,但是如果您正在努力,那么使用SQL Server sp_ExecuteSQL语义重写sproc可能也是值得的。

答案 5 :(得分:0)

我曾经为Sql Server寻找类似于DBMS_ASSERT的东西,但无济于事。 所以我最终编写了一系列我们需要的PROC。

微软应该发布类似的东西,但在此之前,你是独立的。