Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I avoid SQL injection in this EF Core query?

Since EF Core does not currently execute group by queries in the database, I'm using the following query to get the job done (InvoiceQuery is a DbQuery type):

long merchantId = 177;
var invTokens = new List<string> {"qasas", "efsac"};
string inClause = string.Join(",", invTokens);

string query = $@"SELECT i.Token, i.Balance, COALESCE(SUM(i.Amount), 0) AS ProcessingAmount
                  FROM inv.Invoices i
                  WHERE i.Token IN ({inClause})
                    AND i.MerchantId = {merchantId} 
                    AND i.Status = {(int)InvoiceStatus.Scheduled}
                  GROUP BY i.Token, i.Balance";

return await dbContext.InvoicesQuery.FromSql(query).ToListAsync();

The above code runs perfect but I don't like it because it gives me a warning of a 'Possible SQL injection vulnerability'.. I know I can use a #pragma to suppress this warning (that's what I'm currently using).

I have tried passing the query and provide the params to the FromSql method, and that works but the parameter that goes into the IN clause is not getting correctly mapped..

Tried using $"'{string.Join("', '", invTokens)}'" but it didn't work.

Any help would be appreciated

like image 461
Efrain Bastidas Berrios Avatar asked Dec 06 '25 06:12

Efrain Bastidas Berrios


1 Answers

Since EF Core 2.0, you can use a FormattableString, where you can use string interpolation for queries.
String interpolation in FromSql and ExecuteSqlCommand
FormattableString Class

In EF Core 2.0 we added special support for interpolated strings to our two primary APIs that accept raw SQL strings: FromSql and ExecuteSqlCommand. This new support allows C# string interpolation to be used in a 'safe' manner.

The example from the docs:

var city = "London";
var contactTitle = "Sales Representative";

using (var context = CreateContext())
{
    context.Set<Customer>()
        .FromSql($@"
            SELECT *
            FROM ""Customers""
            WHERE ""City"" = {city} AND
                ""ContactTitle"" = {contactTitle}")
            .ToArray();
 }

This will produce:

@p0='London' (Size = 4000)
@p1='Sales Representative' (Size = 4000)

SELECT *
FROM ""Customers""
WHERE ""City"" = @p0
    AND ""ContactTitle"" = @p1
like image 90
kapsiR Avatar answered Dec 08 '25 19:12

kapsiR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!