使用C#和SQL注入创建数据库

时间:2013-02-26 15:06:05

标签: c# .net sql sql-server

我有以下代码用于从C#application

创建一些数据库
SqlConnection myConnection = new SqlConnection(ConnectionString);
string myQuery = "CREATE DATABASE " + tbxDatabase.Text; //read from textbox
myConnection.Open();
SqlCommand myCommand = new SqlCommand(myQuery, myConnection);
myCommand.ExecuteNonQuery();

现在我担心它是否安全,C#会接受黑客输入,如“A; DROP TABLE B”或类似的东西吗?如何让它更安全?

5 个答案:

答案 0 :(得分:4)

表名称和列名称不能参数化,但对于第一道防线,请使用分隔符(如大括号)包装tablename,

string myQuery = "CREATE DATABASE [" + tbxDatabase.Text + "]";

或创建用户定义函数来检查输入的值,例如

private bool IsValid(string tableName)
{
    // your pseudocode
    // return somthing
}

然后在你的代码上,

if (IsValid(tbxDatabase.Text))
{
    SqlConnection myConnection = new SqlConnection(ConnectionString);
    string myQuery = "CREATE DATABASE [" + tbxDatabase.Text + "]";
    myConnection.Open();
    SqlCommand myCommand = new SqlCommand(myQuery, myConnection);
    myCommand.ExecuteNonQuery();
}
else
{
    // invalid name
}

答案 1 :(得分:1)

是的,您的代码非常不安全,另一种方法是创建只接受确切参数的存储过程,以避免动态构建命令。

C#本身不会帮助ypu避免那些事情,它应该嵌入在应用程序逻辑上

答案 2 :(得分:1)

使用存储过程并传递参数

答案 3 :(得分:0)

将实际创建命令放在存储过程中。

请勿将文本框中的文本粘贴到字符串中并运行它。

编辑:好的,所以事实证明CREATE需要一个常量表达式,所以你不能参数化命令。

但是,如果必须在代码中执行此操作,则至少应在将输入连接到字符串之前验证输入。在这种情况下,您不应允许任何包含除-z,A-Z以外的任何表名称。

答案 4 :(得分:0)

实现此目的的安全方法是使用sql函数QUOTENAME()来转义输入。

CREATE PROC example_create_db ( @db_name NVARCHAR(256) )
AS 
    BEGIN
        DECLARE @sql NVARCHAR(1000)
    /*
        QUOTENAME() adds the surrounding []'s
    */

        SET @sql = 'CREATE DATABASE ' + QUOTENAME(@db_name) 
        EXEC sp_executesql
    END