Dapper LIKE query for MySql safe against Sql Injection? - c#

Is this query safe against sql injection in combination with Dapper?
If not, what would be the correct way to write it under MySql?
Or is there a better version without using concat?
string sql = "SELECT * from user_profile WHERE FirstName LIKE CONCAT("%",#name,"%");"
var result = connection.query<profile>(sql, new {name});

There isn't a problem with that code, but another approach is to perform the the concat at the caller, i.e.
const string sql = "SELECT * from user_profile WHERE FirstName LIKE #name;";
var result = connection.Query<Profile>(sql, new {name = "%"+name+"%"});

This is safe because you are not building SQL dynamically at all. Name is just a normal parameter. Actually, it has nothing to do with Dapper.
Using a string concat here is the right choice. Alternatively you could use the SUBSTRING_INDEX function.

Related

Replace multiple variables in a string sql query with actual values in C#

I have the following SQL query as string,
string SQL = SELECT COUNT(1) FROM [dbo].[Incident] INNER JOIN dbo.IncidentNotification on Incident.IncidentID = IncidentNotification.IncidentID WHERE Incident.IncidentID = ?IncidentId? AND Incident.UserId = ?UserId?
I would like to replace it with
sql = SELECT COUNT(1) FROM [dbo].[Incident] INNER JOIN dbo.IncidentNotification on Incident.IncidentID = IncidentNotification.IncidentID WHERE Incident.IncidentID = 943434 AND Incident.UserId = '543'
There could be more variables like this, how should I go about this?
One generally uses SqlCommandBuilder Class to build sql commands. With its structure it allows for replacement of variables before the execution of the command. Plus it helps avoid SQL Injection in most situations.
As the others have mentioned, using SqlCommandBuilder or an ORM would be the suggested best practice.
But to directly answer your question, you wouldn't replace the variables (that's the point of variables), you should provide values for them.
var incidentId = 1345;
var userId = 6789;
var dangerousSQLStatement = $"SELECT * FROM IncidentTable Where Incidient.IncidentID = {incidentId} AND Incidient.UserId = {userId}";
See the documentation for further information.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
https://learn.microsoft.com/en-us/dotnet/api/system.string.format?view=net-5.0

SQLite query not executing properly in a WPF project

I'm working on a WPF application and using SQLite database. I can do every CRUD operation with Entity Framework, but in some specific cases I have to use raw SQL queries, and sometimes it's not returning what I need.
Here is a sample code:
using (var db = new DbContext(AppIO.DatabaseFilePath)) {
var key = 12;
string sql = $"SELECT COUNT(*) FROM SomeTable WHERE SomeField={key}";
var result = db.Database.ExecuteSqlCommand(sql);
}
I simplified the example. Here the result, what I got is -1. I copied the sql string value (after it's built) and executed in SQLiteStuido on the same database and it returned the correct value.
The DatabaseFilePath is correct. The connection is set correctly. I'm checking the same databases (in code and in SQLiteStudio). Any other idea?
Try this:
var result = db.Database.SqlQuery<int>(sql).First();
You have to call SqlQuery method and not ExecuteSqlCommand method. Since SqlQuery returns an IEnumerable you have to call Single. This is a the way to retreive scalar values from a query.
using (var db = new DbContext(AppIO.DatabaseFilePath)) {
var key = 12;
string sql = $"SELECT COUNT(*) FROM SomeTable WHERE SomeField={key}";
var result = db.Database.SqlQuery<int>(sql).Single();
}

razor and cshtml: how to db.Execute for select statement?

I am doing a quick CSHTML page for the purpose of testing.
I need to access database based on the id parameter on the URL:
var id = Request.QueryString["id"];
var db = Database.Open("mydatabase_connection");
var query = "select * from myrecord where id = " + id;
var row = db.QuerySingle(query);
//i am able to display the field (called name) of the selected record in the following way:
#row.name
Obviously, the above approach is subject to security attack. I am hoping to retrieve the record the following way:
var query = "select * from myrecord where id=#0";
var row = db.Execute(query, id);
However, I get runtime error when retrieving the field value:
#row.name
What is the correct way of getting the "row" in the second approach?
Thanks and regards.
Database.Execute is for executing a non-query SQL statement and returns the count of records affected by the SQL statement as an Int.
I think the method you want to use really is Database.QuerySingle, which returns an Object.
ie.
var query = "select * from myrecord where id=#0";
var row = db.QuerySingle(query, id);
Razor:
#row.name
As far as safety from SQL injection goes, this approach is safe. You are passing the URL value into your query as a parameter.
The unsafe way to run the query would be with string concatenation:
var query = "select * from myrecord where id=" + id;
Don't do this! It allows for a malicious user to append SQL statements to your query! Always use parameterized queries instead.

SQL Syntax in C#

I'm trying to understand why in C# if you have a sql string why you would have to put tick (') marks in the following where clause in order for this to work. Could someone please explain the reasoning behind this?
where ProgramServer='" + machineName.ToString() + "' and Active=1;
You can avoid those tick (') marks and use Parameters, They will also save you from SQL Injection.
The reason you see those ticks are because SQL expects string type values to be enclosed in single ticks.
What you're seeing is a dynamically built SQL query in the code. When querying based on a string value, the string must be wrapped in single quotes. The final SQL string would look something like:
select * from someTable where ProgramServer = 'YourMachineName' and Active = 1;
Unfortunately, that is far from the best way to do things. You should be using parameterized queries instead:
var query = "select * from someTable where ProgramServer = #machineName and Active = 1;";
using(var conn = new SqlConnection(connString))
{
var command = new SqlCommand(query, conn);
command.Parameters.Add("machineName", machineName.ToString());
// Execute and get the results
}

NHibernate (c#.net) - automatically map results of a SQLQuery to a dto object

Up to now (with NHibernate) I've used entity mapping and not really got involved with creating raw sql queries - but somethings come up where I need to do exactly that.
The problem I have is I want to automatically map the columns aliases of my query to a Dto object.
This works, but i have to specify the column alias' in the order of the query.
SQL
string sql = "select mycol1 as ColumnOne from mytable";
NHibernate Query
var query = session.CreateSQLQuery(sql)
.AddScalar("ColumnOne", NHibernateUtil.Int32)
.SetResultTransformer(
NHibernate.Transform.Transformers.AliasToBean<MyDtoObject>()
);
MyDtoObject
public class MyDtoObject
{
public int ColumnOne {get;set;}
}
But is there a way to making NHibernate automate the mapping between the columns in the query and the Dto without creating a mapping class?
I've seen some examples of using aliases in the query e.g.
string sql = "select mycol1 as {ColumnOne} as ColumnOne from mytable"; /// ???
But cannot get this to work as the alias {ColumnOne} appear not to be replaced before being sent to the db as a sql statement.
Any idea?
TIA
Sam
Maybe System.Linq.Dymanic will help:
use System.Linq.Dynamic;
string ColumnAlisName = "ColumnOne";
var query = mytable.Select(String.Format("new (mycol1 as {0})",ColumnAlisName));

Categories

Resources