C'è qualcos'altro che il codice deve fare per disinfettare gli identificatori (tabella, vista, colonna) tranne per racchiuderli tra virgolette doppie e virgolette doppie segni presenti nel nome dell'identificatore? I riferimenti sarebbero apprezzati.Correggere l'escape degli identificatori delimitati in SQL Server senza utilizzare QUOTENAME
Ho ereditato un codice base con un sistema ORM (Object-Relational Mapping) personalizzato. SQL non può essere scritto nell'applicazione, ma l'ORM deve ancora generare l'SQL da inviare a SQL Server. Tutti gli identificatori sono indicati con virgolette doppie.
string QuoteName(string identifier)
{
return "\"" + identifier.Replace("\"", "\"\"") + "\"";
}
Se fossi la costruzione di questo SQL dinamico in SQL, vorrei utilizzare il built-in funzione di SQL Server QUOTENAME:
declare @identifier nvarchar(128);
set @identifier = N'Client"; DROP TABLE [dbo].Client; --';
declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = QUOTENAME(@identifier, '"');
print @delimitedIdentifier;
-- "Client""; DROP TABLE [dbo].Client; --"
non ho trovato alcuna documentazione definitiva su come identificatori di escape citati in SQL Server. Ho trovato Delimited Identifiers (Database Engine) e ho anche visto this stackoverflow question sulla disinfezione.
Se fosse necessario chiamare la funzione QUOTENAME solo per citare gli identificatori che è molto traffico verso SQL Server che non dovrebbe essere necessario.
L'ORM sembra essere ben pensato per quanto riguarda SQL Injection. È in C# e precede la porta di NHibernate e Entity Framework ecc. Tutti gli input dell'utente vengono inviati utilizzando gli oggetti SqlParameter di ADO.NET, sono solo i nomi di identificatori di cui sono preoccupato in questa domanda. Questo bisogno di lavorare su SQL Server 2005 e 2008.
Aggiornamento 2010-03-31
Mentre l'applicazione non è supposto per permettere agli utenti di ingresso per i nomi di identificatori nelle query, l'ORM fa via la sintassi della query che ha per entrambe le letture in stile ORM e le query personalizzate. È l'ORM che sto cercando di prevenire in definitiva tutti i possibili attacchi di SQL Injection poiché è molto piccolo e facile da verificare rispetto a tutto il codice dell'applicazione.
Un semplice esempio di interfaccia di query:
session.Query(new TableReference("Client")
.Restrict(new FieldReference("city") == "Springfield")
.DropAllBut(new FieldReference("first_name"));
ADO.NET invia tramite questa query:
exec sp_executesql N'SELECT "T1"."first_name"
FROM "dbo"."Client" AS "T1"
WHERE "T1"."city" = @p1;',
N'@p1 nvarchar(30)',
N'Springfield';
Forse sarebbe utile pensare a come qualcosa di simile questo potrebbe sembrare in NHibernate Query Language (HQL):
using (ISession session = NHibernateHelper.OpenSession())
{
Client client = session
.CreateCriteria(typeof(Client)) \\ <-- TableReference in example above
.Add(Restrictions.Eq("city", "Springfield")) \\ <-- FieldReference above
.UniqueResult<Client>();
return client;
}
Forse dovrei guardare e vedere come nibernare protegge t lui inserisce.
Penso tu voglia dire che dovrei richiedere che la lunghezza dell'input alla mia funzione sia <= 128 caratteri. Ciò ha senso. Il parametro della funzione QUOTENAME T-SQL è nvarchar (128) e restituisce nvarchar (258). Non riesco a vedere come possa mai restituire più di 258 caratteri da un input di 128 caratteri, perché sembra che al massimo ogni carattere sia raddoppiato (256), più un delimitatore di inizio e fine. Puoi dare un esempio di quando QUOTENAME potrebbe troncare? selezionare len (QUOTENAME (replicando (']', 128))), len (QUOTENAME (replicando (']', 129))) rendimenti: 258, null –
Esattamente, la funzione è necessario verificare che il l'input è <= 128 caratteri. La stessa funzione QUOTENAME di T-SQL non tronca mai: il troncamento da tenere a mente sta assegnando il valore di ritorno della tua funzione C# QuoteName a una variabile nvarchar (258) in SQL (dinamico). Finché la tua funzione C# QuoteName richiede che l'input sia <= 128 caratteri, ad esempio si comporta come la funzione QUOTENAME di T-SQL, non hai nulla di cui preoccuparti. –