Scrittura di istruzioni SQL dinamiche protette in SQL Server (ADO.NET)
Per SQL injection si intende il processo mediante il quale un utente malintenzionato immette istruzioni Transact-SQL anziché input valido. Se l'input viene passato direttamente al server senza essere convalidato e se l'applicazione esegue inavvertitamente il codice inserito, è possibile che l'attacco danneggi o elimini permanentemente i dati.
Per la prevenzione degli attacchi di questo tipo è necessario esaminare tutte le procedure che creano istruzioni SQL, poiché in SQL Server vengono eseguite tutte le query sintatticamente valide ricevute. Anche i dati con parametri possono essere modificati da un utente malintenzionato abile e determinato. Se si utilizzano istruzioni SQL dinamiche, aggiungere parametri ai comandi e non includere mai i valori dei parametri direttamente nella stringa di query.
Anatomia di un attacco SQL injection
Il processo di injection termina prematuramente una stringa di testo e aggiunge un nuovo comando. Poiché prima che venga eseguito è possibile che al comando inserito vengano aggiunte ulteriori stringhe, l'utente malintenzionato termina la stringa inserita con un contrassegno di commento "--". In fase di esecuzione il testo che segue il contrassegno di commento viene ignorato. È possibile inserire più comandi utilizzando il punto e virgola (;) come delimitatore.
Se il codice SQL inserito tramite injection è corretto dal punto di vista sintattico, le manomissioni non possono essere rilevate a livello di codice. È pertanto necessario convalidare tutto l'input utente ed esaminare attentamente il codice per l'esecuzione dei comandi SQL generati nel server in uso. Non eseguire mai la concatenazione di input utente non convalidato. La concatenazione delle stringhe costituisce il punto di ingresso principale per un attacco script injection.
Di seguito sono riportate alcune linee guida utili.
Non compilare mai istruzioni Transact-SQL direttamente dall'input utente. Utilizzare stored procedure per la convalida dell'input utente.
Convalidare l'input utente testando tipo, lunghezza, formato e intervallo. Utilizzare la funzione QUOTENAME() Transact-SQL per utilizzare caratteri di escape per i nomi di sistema oppure la funzione REPLACE() per utilizzare caratteri di escape per qualsiasi carattere di una stringa.
Implementare più livelli di convalida per ciascun livello dell'applicazione.
Testare le dimensioni e il tipo di dati dell'input e imporre limiti appropriati. In questo modo è possibile impedire intenzionali sovraccarichi del buffer.
Testare il contenuto delle variabili stringa e accettare solo i valori previsti. Rifiutare voci contenenti dati binari, sequenze di escape e caratteri di commento.
Quando si utilizzano documenti XML, convalidare tutti i dati in base al relativo schema man mano che vengono immessi.
In ambienti multilivello è necessario convalidare tutti i dati prima di consentirne l'inserimento nell'area attendibile.
Non accettare le stringhe seguenti in campi da cui è possibile creare nomi di file: AUX, CLOCK$, da COM1 a COM8, CON, CONFIG$, da LPT1 a LPT8, NUL e PRN.
Utilizzare oggetti SqlParameter con stored procedure e comandi per fornire la verifica dei tipi e la convalida della lunghezza.
Utilizzare espressioni Regex nel codice client per filtrare i caratteri non validi.
Strategie per le istruzioni SQL dinamiche
L'esecuzione di istruzioni SQL create in modo dinamico nel codice procedurale interrompe la catena di proprietà, facendo in modo che SQL Server controlli le autorizzazioni del chiamante sugli oggetti cui hanno accesso le istruzioni SQL dinamiche.
Per utilizzare istruzioni SQL dinamiche, in SQL Server 2000 è necessario concedere autorizzazioni sulle tabelle sottostanti, lasciando l'applicazione vulnerabile ad attacchi SQL injection.
In SQL Server 2005 vengono introdotte due nuove tecniche per concedere agli utenti l'accesso ai dati utilizzando stored procedure e funzioni definite dall'utente che eseguono istruzioni SQL dinamiche.
L'utilizzo della rappresentazione con la clausola EXECUTE AS Transact-SQL, come descritto in Personalizzazione delle autorizzazioni mediante la rappresentazione in SQL Server (ADO.NET).
La firma di stored procedure con i certificati, come descritto in Firma di stored procedure in SQL Server (ADO.NET).
EXECUTE AS
La clausola EXECUTE AS sostituisce le autorizzazioni del chiamante con quelle dell'utente specificato nella clausola stessa. Le stored procedure o i trigger annidati vengono eseguiti nel contesto di sicurezza dell'utente proxy. Tale comportamento può causare l'interruzione di applicazioni che si basano sulla sicurezza a livello di riga o che richiedono controlli. Alcune funzioni che restituiscono l'identità dell'utente restituiscono in realtà l'utente associato alla clausola EXECUTE AS e non il chiamante originale. Viene ripristinato il contesto di esecuzione del chiamante originale solo dopo l'esecuzione della stored procedure o quando viene eseguita un'istruzione REVERT.
Firma dei certificati
Quando viene eseguita una stored procedure firmata con un certificato, le autorizzazioni concesse all'utente del certificato vengono unite con quelle del chiamante. Il contesto di esecuzione rimane lo stesso. L'utente del certificato non rappresenta il chiamante. L'implementazione della firma delle stored procedure richiede l'esecuzione di numerosi passaggi. Una stored procedure deve essere firmata nuovamente a ogni modifica.
Accesso tra database
Il concatenamento della proprietà tra database non funziona nei casi in cui vengono eseguite istruzioni SQL create in modo dinamico. Per aggirare questo problema, in SQL Server 2005 è possibile creare un stored procedure che accede ai dati di un altro database e firmare la procedura con un certificato disponibile in entrambi i database. In questo modo si fornisce agli utenti l'accesso alle risorse del database utilizzate dalla procedura senza concedere loro l'accesso o le autorizzazioni per il database.
Risorse esterne
Per ulteriori informazioni, vedere le seguenti risorse.
Risorsa |
Descrizione |
---|---|
Stored Procedures e SQL Injection nella documentazione online di SQL Server 2008 (informazioni in lingua inglese) |
Viene descritto come creare stored procedure e come funziona SQL Injection. |
Stored procedure e Attacco intrusivo nel codice SQL nella documentazione online di SQL Server 2005 |
Viene descritto come creare stored procedure e come funziona SQL Injection. |
Stored Procedures e Using Ownership Chains nella documentazione online di SQL Server 2000 (informazioni in lingua inglese) |
Viene descritto come creare stored procedure e come trarre vantaggio dalle catene di proprietà in SQL Server 2000. |
Nuovi attacchi di troncamento SQL e metodi per evitarli in MSDN Magazine. |
Viene descritto come delimitare caratteri e stringhe, SQL injection e modifiche da attacchi di troncamento. |
Vedere anche
Concetti
Scenari di sicurezza delle applicazioni in SQL Server (ADO.NET)
Gestione delle autorizzazioni con le stored procedure in SQL Server (ADO.NET)
Firma di stored procedure in SQL Server (ADO.NET)
Personalizzazione delle autorizzazioni mediante la rappresentazione in SQL Server (ADO.NET)