Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#和SQL注入中创建数据库_C#_.net_Sql_Sql Server - Fatal编程技术网

在C#和SQL注入中创建数据库

在C#和SQL注入中创建数据库,c#,.net,sql,sql-server,C#,.net,Sql,Sql Server,我有以下代码用于从C#应用程序创建一些数据库 SqlConnection myConnection = new SqlConnection(ConnectionString); string myQuery = "CREATE DATABASE " + tbxDatabase.Text; //read from textbox myConnection.Open(); SqlCommand myCommand = new SqlCommand(myQuery, myConnection); my

我有以下代码用于从C#应用程序创建一些数据库

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;删除表B”或类似的东西吗?如何使其更安全?

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

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
}

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

不要只是将文本框中的文本粘贴到字符串中并运行它

编辑:好的,结果表明CREATE需要一个常量表达式,所以不能参数化该命令


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

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


C本身不会帮助ypu避免这些事情,它应该嵌入到应用程序逻辑中

使用存储过程并传递参数

实现这一点的安全方法是使用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

我同意您的验证建议,但是在表名中添加括号如何提供安全性呢?例如,
“test]drop database xxx——”
如果要将用户输入连接到查询中,至少应该首先验证文本。在这种情况下,如果提交的表名不包含字母ascii(编辑:“ascii”表示没有扩展字符,只有a-z a-z),您可能会拒绝该请求。Sql Server提供QUOTENAME()函数来转义Sql标识。虽然您可能希望对名称实施某些限制(例如,没有空格或特殊字符),但这应该是正确转义输入的补充(请参阅下面的答案)。使用此帖子建议使用参数,这是最好的方法,这是针对值,而不是表名。您尝试的是非常危险的。如果我必须像你一样做同样的事情,我不会担心黑客来插入“drop table B”,但我会担心让黑客进入该页面。保护页面会更容易每个人都在谈论存储过程,但它们属于某个数据库,我只是创建一个新的空数据库。所以要有存储过程,我首先需要有一个我没有的基。我错过什么了吗???