I allow users to enter their own SQL statement to execute, but only if it is a SELECT statement. Is there a way to determine if the SQL statement is anything other than this, i.e. ALTER, INSERT, DROP, etc.? I will worry about other issues, such as a query blocking a table and so on, but this is more of a proof of concept right now. I can restrict the service account on the server on which the application is running so that it has read rights only for db, but I am interested in how it is processed in the application.
This is my approach to it, discovering the first word of the query, but it seems vulnerable. Is there a cleaner way to make this detection?
public void ExecuteQuery(string connectionString, int id)
{
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();
}
}
}