DBMS_ASSERT 是防止Oracle中SQL注入攻击的关键之一。我尝试了一个粗略的搜索...是否有任何SQL Server 2005/2008等效于此功能?
我正在寻找一个特定的实现,它具有DBMS_ASSERT的所有相应Oracle包成员的对应物。
我知道防止注射的最佳做法...绑定变量......就是其中之一 但是,在这个问题中,我特意寻找一种清理输入的好方法......在没有使用绑定变量的情况下。
您是否有任何具体的实施方案? 是否有一个实际上是Oracle软件包的SQL Server端口的库?
答案 0 :(得分:2)
不要通过构建字符串并执行它们来进行动态查询。
使用sp_executesql
并将参数作为参数传递。
你会发现sql注入不再存在。
编辑:对不起,我匆忙写了错误的命令。它不是sp_execute,它是sp_executesql;它需要一个字符串和一组参数:所有参数的编码和转义都是由SQL Server完成的。
答案 1 :(得分:2)
我最接近的是TSQLAssert for TSQLMacro,但它只支持TSQL存储过程。它是免费的。
TSQLAssert是一个断言框架 建立在TSQLMacro之上。它是 旨在提供调试时间 断言失败类似于 C ++等语言中的断言 - 带有额外的日志记录组件 没有找到那些语言。 TSQLAssert只能在其中使用 存储过程和触发器 - 不幸的是,用户定义的功能 并且观点不支持许多 允许它工作的关键字。
答案 2 :(得分:1)
没有神奇的“防止注射”命令。该方法是以下的组合:
答案 3 :(得分:1)
因此,SQL SERVER中没有DBMS_ASSERT。
然而,通过这个链接增强了Aaron Bertrand的答案 SQL Injection
答案 4 :(得分:1)
唯一可能的选项是QUOTENAME
,它用于转义对象名称(因此可能是SIMPLE_SQL_NAME
或ENQUOTE_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。
微软应该发布类似的东西,但在此之前,你是独立的。