I couldn’t believe it when I read Julie Lerman’s post about EF and SQL Injection. She discovered that Entity Framework doesn’t use parameterized queries always!
I had to try it for myself on Northwind database:
var query = from c in entities.Customers
where c.ContactName == "Tubo"
select c;
produces this SQL statement (courtesy of SQL Profiler):
SELECT
[Extent1].[CustomerID] AS [CustomerID],
[Extent1].[CompanyName] AS [CompanyName],
[Extent1].[ContactName] AS [ContactName],
[Extent1].[ContactTitle] AS [ContactTitle],
[Extent1].[Address] AS [Address],
[Extent1].[City] AS [City],
[Extent1].[Region] AS [Region],
[Extent1].[PostalCode] AS [PostalCode],
[Extent1].[Country] AS [Country],
[Extent1].[Phone] AS [Phone],
[Extent1].[Fax] AS [Fax]
FROM [dbo].[Customers] AS [Extent1]
WHERE N'Tubo'= [Extent1].[ContactName]
See the Tubo condition expressed like a string? Speechless. Granted, if you specify a variable instead a string within the EF query then a parameter is used.
So I tried a classic SQL Injection attack, like this:
var query = from c in entities.Customers
where c.ContactName == "Tubo'; UPDATE [Northwind].Categories SET Description='SQL Injection' WHERE CategoryID=9; --'"
select c;
which produces this condition (select columns trimmed)
WHERE N'Tubo''; UPDATE [Northwind].Categories SET Description=''SQL Injection'' WHERE CategoryID=9; --''' = [Extent1].[ContactName]
Luckily the attack fails due to duplication of single quotes. So there is a protection against SQL attacks afterall.
However, I am not feeling safe with this approach. Attackers are smart and sooner or later they might find a way across string-replacement defense strategy.
But the real questions is: why leave the door open to a possible attack in first place? Why not always use parameters as there is no way around them? What good is to risk a SQL injection attack?
Update: A possible scenario where one could exploit this feature, granting there is a way around single-quote-replacement, is with add-ins. Imagine you have an add-in based application where each add-in is allowed to perform EF selects on database (enforced by your application). One could fake a select with all sort of T-SQL code nested within.
Clik here to view.
