我有以下代码用于从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”或类似的东西吗?如何让它更安全?
答案 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