我允许用户输入自己的SQL语句来执行,但前提是它是一个SELECT语句。有没有一种方法可以检测SQL语句是否除此之外,即ALTER,INSERT,DROP等?我会担心其他问题,比如稍后查询锁定表格等,但这更像是现在的概念证明。我可以限制运行应用程序的服务器上的服务帐户在数据库上拥有只读权限,但我有兴趣看到它在应用程序中处理。防止非SELECT语句
这是我通过检测查询的第一个单词的方法,但这似乎很脆弱。有没有更干净的方法来做这种检测?
public void ExecuteQuery(string connectionString, int id)
{
//The SQL statement will be user input
var sql = "SELECT ColumnA, ColumnB, ColumnC FROM MyTable where MyTableId = @Id";
var split = sql.Split(' ');
if (split[0].ToUpper() != "SELECT") Console.WriteLine("Only use a SELECT statement.");
else
{
using (var connection = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.AddWithValue("@Id", SqlDbType.Int);
cmd.Parameters["@Id"].Value = id;
connection.Open();
var reader = cmd.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine($"{reader["ColumnA"]}, {reader["ColumnB"]},
{reader["ColumnC"]}");
}
}
finally
{
reader.Close();
}
cmd.ExecuteNonQuery();
}
}
}
将整个事物包装在一个'TransactionScope'中,并且永远不会提交,所以无论他们做什么,都会回滚任何DML。 – Crowcoder
您可以管理SQL Server上的用户权限吗?因为无论帐户在执行SQL,您只应授予SELECT权限。我认为这将是您提出的解决方案或任何基于“代码”的解决方案的首选解决方案。 – SimonGates
为什么你让用户创建自己的SQL语句?这只是一个非常糟糕的主意。从sys.columns,sys.columns,sys.columns中选择*,整个系统就会瘫痪几个小时。对我来说,概念的证明应该是为什么永远不要让这种类型的应用程序靠近sql数据库。 –