Open mgirolet-gl opened 3 months ago
Hello @mgirolet-gl,
I am not able to reproduce the issue.
Which framework are you using to execute the query?
What is the type of db
?
Thank you,
Hello @mgirolet-gl,
I am not able to reproduce the issue.
Which framework are you using to execute the query? What is the type of
db
?Thank you,
Hi,
I am using .NET 6.0 with ASP.NET.
db
is a MySqlConnection
, a child class of System.Data.Common.DbConnection
instanciated using the MySql.Data
NuGet Package.
The issue also raises with syntax like $"SELECT id FROM users {(onlyEnabled ? "WHERE enabled = 1" : "")}"
, if it can help reproduce it.
Thanks.
MySqlConnection
does not seem to have a Query
method.
Is it an extension method?
Could you provide me with a small project that reproduces the issue?
My apologies, it seems that the Query method is indeed an extension from Dapper, which we use to pass parameters to queries.
My example didn't provide parameters to queries so I ommited Dapper's inclusion.
I will update the issue accordingly. I cannot make an example project as of now but will try to do so whenever I can unless you can reproduce the issue in the meantime.
Thank you
Hello @mgirolet-gl,
I was not able to reproduce your initial error. However, when using a ternary inside a formatted string, I am able to reproduce. So far, I came down to this:
public void ConstantQuery(MySqlConnection db, bool onlyEnabled)
{
string query = "SELECT id FROM users";
if(onlyEnabled)
query += " WHERE enabled = 1";
db.Query<int>(query); // This is fine
db.Query<int>($"SELECT id FROM users {(onlyEnabled ? "WHERE enabled = 1" : "")}"); // S2077 is raising here
}
I will add this to the backlog but only for the ternary in a formatted string. Unless you can provide a reproducer, we won't be able to fix the initial issue.
I cannot reproduce the initial issue either on a separate project. Might be an oddity with my project that'll require further investigation on my side.
I will update the issue to mention the ternary inside of a formatted string since it can be consistently reproduced.
Description
S2077 is a Security Hotspot rule that raises when an SQL query is dynamically formatted. However, it doesn't detect what the query is made out of.
The "What's the risk?" and "Assess the risk" sections say:
However, if the formatted query is only made out of constant strings, including those decided by ternaries and functions that only use constant strings too, then there is no risk of SQL injection, untrusted user values, or anything else that'd otherwise be a good reason to raise a Security Hotspot.
Repro steps
In the first example below, we add a constant string to the query if a boolean is set to
true
. This poses absolutely no safety threat, since it is clear here that every character the query is made out of was written safely by the programmer, even if it the end query will be different depending of a user-provided boolean. Yet, the function raises S2077.The function below it is functionally equivalent to the first one, and does not raise S2077, but is clearly less maintainable, repeats part of the query (which infringes the second point of the "Assess the risk" section by the way) and is overall much less practical to work with.
The second example adds a constant string to the query from a function's return value. This doesn't pose a safety threat either for the same reasons as the first exemple.
The compliant version below it on the other hand is less maintainable for the same reasons.
Expected behavior
If the dynamically formatted SQL query uses only constant strings, no Security Hotspot should be raised.
Actual behavior
A Security Hotspot is raised as soon as anything in the query is dynamically formatted, regardless of the way it is done.
Known workarounds
Marking the Security Hotspot as Safe, or duplicating the whole query, both of which are impractical.
Related information