Sono a metà di "Pen Test" e sto cercando di trovare il modo "più sicuro" per utilizzare Entity Framework Core
in Stored Procedure. Penseresti che sarebbe ovvio, ma per favore continua a leggere.
sfondo
Utilizzando questo documento sull'utilizzo di Raw SQL e avendo letto le novità di .NET Core 2.0, il mio codice iniziale utilizzava l'interpolazione delle stringhe (mostrata come sicura nel documento 'what's new').
Tuttavia, il Pen Test ha gestito con successo un attacco sql injection contro di esso.
Esempio di codice offendente:
dbResults = _datacontext.Blogs.FromSql($"myStoredProcedure @parmeter1 = {parmeter1String}");
Così, ho cambiato il codice per utilizzare i parametri, ma hanno anche rotto questo:
dbResults = _datacontext.Blogs.FromSql("myStoredProcedure @parmeter1 = {0}", parmeter1String);
e hanno rotto questo (anche se forse non stavo pulendo abbastanza - almeno ho fermato exec
):
dbResults = _datacontext.Blogs.FromSql("myStoredProcedure @parmeter1 = {0}", parmeter1String.ToCleanedSqlString());
Quindi la risposta è usare SqlParameter (non mostrato in nessuno dei documenti / esempi sopra)?
dbResults = _datacontext.Blogs.FromSql("myStoredProcedure @parmeter1 = {0}", new SqlParameter("@parmeter1", parmeter1String));
o c'è un modo migliore?
Una guida definitiva sarebbe apprezzata per favore.
EDIT seguente commento:
Aggiunta importante: la stored procedure esegue sql dinamico, ma quella procedura non è nella mia applicazione e non ho il controllo su di essa. Devo chiamarlo.
Dopo i commenti, ho pensato di aggiungere una conclusione (grazie @AlexK tramite commento).
Se una procedura memorizzata viene scritta utilizzando sql dinamico non parametrizzato, Entity Framework non può proteggerla. Questo non è un difetto di Entity Framework (che, in generale, è molto bravo nella protezione sql).
Se ti trovi in una situazione simile, la procedura memorizzata deve essere riscritta usando sql dinamico parametrizzato. Una spiegazione molto valida può essere trovata qui .
Elaborare.
Entity Framework non può proteggere sql in questo modo:
CREATE PROCEDURE search_orders @custid nchar(5) = NULL,
@shipname nvarchar(40) = NULL AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ' SELECT OrderID, OrderDate, CustomerID, ShipName ' +
' FROM dbo.Orders WHERE 1 = 1 '
IF @custid IS NOT NULL
SELECT @sql = @sql + ' AND CustomerID LIKE ''' + @custid + ''''
IF @shipname IS NOT NULL
SELECT @sql = @sql + ' AND ShipName LIKE ''' + @shipname + ''''
EXEC(@sql)
Ma questo sarà sicuro:
CREATE PROCEDURE search_orders @custid nchar(5) = NULL,
@shipname nvarchar(40) = NULL AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ' SELECT OrderID, OrderDate, CustomerID, ShipName ' +
' FROM dbo.Orders WHERE 1 = 1 '
IF @custid IS NOT NULL
SELECT @sql = @sql + ' AND CustomerID LIKE @custid '
IF @shipname IS NOT NULL
SELECT @sql = @sql + ' AND ShipName LIKE @shipname '
EXEC sp_executesql @sql, N'@custid nchar(5), @shipname nvarchar(40)',
@custid, @shipname
Per quanto ne so, uno qualsiasi degli esempi di codice della domanda sarebbe un codice EF "sicuro" valido (sebbene il lavoro extra sul metodo di estensione sarebbe stato un surplus rispetto ai requisiti).
Aggiornare
Successivamente, ho contattato Microsoft e creato un PR , la cui base è stata accettata. Il messaggio di avvertimento sulla documentazione ufficiale è ora più dettagliato , speriamo di ridurre la possibilità che qualcuno abbia gli stessi problemi.