.NET / SQL中的参数化表名?

时间:2008-12-16 17:30:25

标签: sql .net sql-server parameters

正如主题所示,我希望能够使用.NET(实际上与哪种语言无关)和SQL Server将表名作为参数传递。

我知道如何为数值执行此操作,例如command.Parameters.AddWithValue("whatever", whatever)在查询中使用@whatever来表示参数。问题是,我希望能够在查询的其他部分(例如列和表名称)中执行此操作。

这不是一个理想的情况,但它是我必须使用的,它不太容易SQL注入,因为只有使用代码的人可以设置这些表名而不是最终用户。但是很麻烦。

那么,我问的是可能的吗?

编辑:为了明确说明SQL注入,表格名称仅由源代码传递,具体取决于具体情况。开发人员指定了这一点。开发人员无论如何都可以访问数据库层,所以我要问的原因不是安全性,而是为了使代码更清晰。

7 个答案:

答案 0 :(得分:5)

您无法直接参数化表名。您可以通过sp_ExecuteSQL间接执行此操作,但您也可以在C#中构建(参数化)TSQL(连接表名但不连接其他值)并将其作为命令发送。你得到了相同的安全模型(即你需要明确的SELECT等,并假设它没有签名等)。

另外 - 请务必将表名列入白名单。

答案 1 :(得分:4)

您可以将表名作为参数传递,就像任何其他参数一样。关键是你必须构建一个动态的sql语句,然后你应该考虑是否更容易在你的应用程序层或procs中构建它。

create procedure myProc

@tableName nvarchar(50)

as

sp_executesql N'select * from ' + @tablename

这个代码示例来自内存,看看BOL是否有正确的sp_executesql语法。

此外,对于SQL注入来说,这是非常容易理解的,因为您指出这对您来说不是问题,但阅读此内容的任何人都应该非常谨慎地接受来自用户的输入以生成这样的查询。

答案 2 :(得分:3)

SQL查询参数只能取代文字值。您不能将参数用于表名,列名,值列表或其他SQL语法。这是所有品牌数据库的标准SQL行为。

使表名动态化的唯一方法是在将该字符串作为语句准备之前,将变量插入到SQL查询中。

顺便说一句,如果您认为这不是SQL注入的风险,那么你就是在愚弄自己。如果将表名称动态插入到查询中,则需要在表名周围使用 delimited identifiers ,就像使用从变量插值的字符串文字周围的引号一样。 / p>

答案 3 :(得分:3)

我不我见过的任何SQL方言都有这种能力,但它不是专业领域。

我建议将字符限制为AZ,az,0-9,'。','_'和'' - 然后对数据库使用任何适当的包围(例如[],对于SQL Server,我相信)包裹整个事物。然后直接将它放在SQL中。

关于它不是SQL注入风险的意思并不完全清楚 - 你的意思是名称将在源代码中并且仅在源代码中吗?如果是这样,我同意让事情变得更好。您可能甚至不需要自动进行包围,如果您信任您的开发人员不要做到(有意或无意)。

答案 4 :(得分:2)

不容易进行SQL注入的想法是错误的。它可能倾向于从前端用户注入SQL,但它仍然非常容易注入SQL。大多数对数据库的攻击来自被攻击的公司内部,而不是来自最终用户。

员工可能有怨恨,他们可能是不诚实的,他们可能心怀不满,或者他们可能只是不那么聪明,并认为可以绕过安全来做任何他们认为应该做的事情完成数据库。

答案 5 :(得分:0)

请用户Vimvq1987查看此帖子的回答: MySqlParameter as TableName

基本上,您首先根据模式检查表名,其中表名以参数化方式使用。然后,如果一切正常,表名是合法的。

释义的基本思想是:

    SELECT table_name
    FROM information_schema.tables
    WHERE table_schema = 'databasename'
    AND table_name = @table;

    cmd.Parameters.AddWithValue("@table",TableName);

如果使用表名返回ok,请继续使用主查询...

答案 6 :(得分:0)

我会检查一下 select OBJECT_ID(@tablename) 我的想法是防止注入,你知道它必须是表名,如果这返回一个数字然后我会运行实际的查询,