2012-12-14 89 views
0

可能重复:
Sanitize table/column name in Dynamic SQL in .NET? (Prevent SQL injection attacks)避免SQL注入的查询与表名

我有一个查询,像这样:

"SELECT * FROM MyTable_" + myID + " WHERE variable = @variable"; 

的SQL参数适用于变量,但我如何使它与表名一起工作? myID是一个i​​nt我传入并更改(可以转换为字符串),但我如何防止SQL注入在这里?

+2

[白名单](http://en.wikipedia.org/wiki/Whitelist) - 这是你的下一个最好的朋友。请参阅[我的相关问题]的答案(http://stackoverflow.com/questions/9651582/sanitize-table-column-name-in-dynamic-sql-in-net-prevent-sql-injection-attack)至少有3种可能的方法:过滤器(真白名单),警卫(启发式白名单),报价/退出。 – 2012-12-14 22:34:47

+1

为什么'myID'不是'MyTable'中的另一列?这是一个多租户应用程序吗? –

+0

同意@pst。表名列表是有限的;对比所有的输入。 –

回答

4

敢问为什么你这样做,但你可以看看sys.tables一个决定性的白名单。

DECLARE @TableName VARCHAR(100) = 'Table to Look for'; 
DECLARE @Exists BIT = (SELECT CAST(COUNT(1) AS BIT) FROM sys.tables WHERE name = @TableName AND type = 'U'); 

您可以参数化初始输入,但白名单方法仍然很重要。否则,恶意用户可能会在整个数据库中传递任何有效的表名,并且查询会针对它运行(假设它们具有SELECT权限)。

+0

我是否会在病房后面抓住@exists进行测试,如果存在,然后运行我的查询? – cdub

+0

是,例如'IF(@Exists = 1)BEGIN' –

1

获取数据库中的表的列表,并检查"MyTable_" + myID是在该列表中。

5

只要myID是数值变量,它可以不包含任何有害的代码。

,你需要做的唯一的其他东西,是从试图读取并不存在的表确认错误信息,不泄露有关数据库布局信息这有可能有助于一些其他类型的攻击。

+0

好点。 。 。 –

+0

是的,我意识到,因为myId是在另一个表中,我可以测试它存在那里,如果它是,它是数字,可以继续。 – cdub

-1

改型设计是答案,没有动态的表名。在表格中有一个表示您的原始表名的值,并且对于所有当前表都只有一个表。

如果你坚持现有的东西有可向后兼容,你可以(也应该)相结合的方法对系统的其他部分兼容。转义,白名单或引用都是可行的,我会说选择两个。

当我说“引用” - 把所有有效名称列表中,整数关口指数挑一。

+0

重新设计*可以成为答案,但某些情况(例如处理动态输入数据和自动化流程)需要使用动态表。 – Stijn

+0

@Stijn绝对没有理由拥有动态名称(直到你用一个我无法重构的例子证明它)。动态名称最有可能意味着只有一个参考表。我真的很好奇看到这样的例子,如果没有动态的东西就不能解决 –

+0

@Stijn事实上,接受的答案证明:这是用作参考表的sys.tables表格 –