New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
String interpolation in 2.0 is a breaking change when injecting parameters in invalid places #9734
Comments
As a workaround, you can explicitly cast the interpolation to "string" (so the FormattableString overload isn't used and the parameters aren't extracted): this.Database.ExecuteSqlCommand((string)$"ALTER DATABASE [{databaseName}] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)"); |
@jelledruyts When we updated EF Core to use string interpolation to do parameterization we recognized this as a breaking change for code that was already using it to do things other than parameterization. The guidance going forward is to not let EF do it's parameterization in this case, possibly by casting to string like you show. However, be careful that this does not open your code to SQL injection attacks by making sure that all data is correctly escaped, especially when coming from user input. |
@ajcvickers Is there any chance we can get this feature removed in a future version? It's such a dangerous feature that makes the user think they're protected when in many cases they are not. For example, if they have |
@NickCraver - It worked like that even before we added overload in 2.0. |
@smitpatel It's not all all obvious to a user that this escapes: this.Database.ExecuteSqlCommand($"....{..}..."); but this does not: var sql = $"....{..}...";
this.Database.ExecuteSqlCommand(sql); There's a lot of information telling people that this is safe now, but the actual overload and resolution rules make it very brittle and there are even a lot of refactorings (e.g. do this replacement once) that unwittingly break it, even introducing SQL injection rather silently. It's much better, IMO, to tell users to explicitly parameterize. We've very explicitly stayed away from doing this with Dapper because the messaging is so dangerous, and we see a lot more raw SQL than any other library. I posted a repo (that you can run) showing just some of the injection cases and some of the many ways users can easily screw this up: https://github.com/NickCraver/EFCoreInjectionSample/blob/master/Program.cs |
If you provide only a The method that takes a raw string could have the suffix |
In EF Core 1.x the following worked as expected:
In EF Core 2.0 the new string interpolation feature extracts the "databaseName" and injects it as a parameter, but SQL Server doesn't allow the database name to be parameterized so it throws an exception:
Further technical details
EF Core version: Microsoft.EntityFrameworkCore.SqlServer version 2.0.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 version 1703
IDE: Visual Studio 2017.3
The text was updated successfully, but these errors were encountered: