表名sql注入

本文关键字:注入 sql 表名 | 更新日期: 2023-09-27 18:21:11

我正在使用C#。我需要编写一个选择内联查询。

表名应取自config。我无法编写存储过程。

SqlCommand myCommand= new SqlCommand();
myCommand.CommandText = "Select  * from " + tableName;
myCommand.CommandType = CommandType.Text;
myCommand.Connection = connString;

如何避免sql注入?

表名sql注入

只需创建一个带有真实参数的查询,并检查表名是否存在,比如:

SELECT COUNT(*) FROM SYS.TABLES WHERE NAME = @pYOURTABLENAME

如果返回1,那么您就知道该表存在,因此可以在问题中显示的SELECT中使用它。。。

然而,我强烈建议您尝试任何方法来消除对任何易于SQL注入的代码的需求

我会确保表名只包含以下字符:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz[]. -_0123456789

例如,

Regex regex = new Regex(@"^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[']. -_0123456789]{1,128}$");
if (!regex.IsMatch(tableName)) throw new ApplicationException("Invalid table name");

要进行更全面的工作,包括非英语语言,请参阅以下关于有效表名称的参考:http://msdn.microsoft.com/en-us/library/ms175874.aspx

您需要验证tableName是否合适。在进行了一些健全性检查(确保它没有空格或其他不允许使用的表名字符等)后,我将首先在数据库中查询所有表的名称,并通过编程验证它是否是这些表名之一。然后继续运行您显示的查询。

我会考虑将SQL迁移到存储过程中,并回顾Erland Sommarskog的这篇文章,因为它对在存储过程中使用动态SQL有一些很好的想法。我当然会研究一下。它讨论了许多关于SQL注入的问题,以及动态SQL的可能替代方案。

他还有另一篇关于如何在存储过程中使用数组的伟大文章。我知道你没有要求这样做,但我经常提到这两篇文章,因为我认为它们很有见地,为你编写程序提供了一些有用的想法。

除了上面链接的一些建议之外,如果我使用动态SQL,我仍然可以使用一些基本的参数净化机制。这方面的一个例子如下;

        IF LEN(@TableName) < 5 OR LEN(@TableDisplayName) < 5
    BEGIN
        RAISERROR('Please ensure table name and display name are at least 5 characters long', 16, 1)
    END
    IF NOT (@TableName not like '%[^A-Z]%') 
    BEGIN
        RAISERROR('The TableName can only contain letters', 16, 1)
    END
    IF NOT (@TableDisplayName not like '%[^0-9A-Z ]%') 
    BEGIN
        RAISERROR('The TableDisplayName can only contain letters, numbers or spaces', 16, 1)
    END

再加上在动态sql中使用参数,然后使用sp_executesql执行,这无疑有助于将sql注入攻击的可能性降至最低。