Algoritmo per evitare l’iniezione SQL su MSSQL Server dal codice C #?

Quale sarebbe il modo migliore per evitare l’SQL injection sulla piattaforma C # .net.

Si prega di inviare un’implementazione C # se ne avete.

Le 10 migliori cose che possiamo fare per essere sicuri (nessuno di questi farà tutto.)

  1. Adotta l’idea che “Tutti i dati sono malvagi”. Tutti i dati, anche i dati memorizzati nel database o sul nostro file system sono sospetti. Non solo l’immissione di dati da app esterne al nostro firewall come stringhe di query, campi modulo, cookie, ecc. Qualsiasi cosa può essere utilizzata per compromettere un sistema.

  2. Non fare affidamento sulla convalida sul lato client delle lunghezze dei campi javascript o html o anche delle API Web sul lato server che utilizzano la convalida lato client. Usalo per migliorare l’usabilità, ma non fare affidamento su di esso come unica protezione. Scopri come i validatori forniti da API come NET funzionano. Non li dare per scontato. Ci sono modi per aggirarli.

  3. Fai corrispondenze positive per catturare tutti i dati mentre entra. Se i dati corrispondono agli intervalli di caratteri di un’espressione regolare, allora va bene. Ciò non consente di inserire nel nostro database strani caratteri unicode che potrebbero delimitare accidentalmente qualcosa in sql o creare altri problemi come gli XSS / Attacchi di phishing. Al contrario, la corrispondenza negativa richiede liste di tutti i personaggi cattivi, che sembrano crescere continuamente. Questo è un approccio sbagliato. La corrispondenza positiva è migliore. Respingiamo i cattivi dati, non disinfettiamo o evitiamo.

  4. Quando ansible, considera di filtrare, contrassegnare o catturare i dati di stringa con “aggiorna”, “elimina”, “rilascia”, “seleziona”, “altera”, ecc. Ciò potrebbe non essere ansible data la natura della stringa. “1212 Lemondrop Ln”, “Waltersburg, PA” e “Table Rock, NE” sono campi di indirizzi validi. Eseguendo una scansione giornaliera di tutti i dati della tabella per i campi che corrispondono a uno di questi potrebbero rivelare attacchi o vulnerabilità ritardate. È ansible utilizzare anche la registrazione, il bando IP, gli avvisi e-mail, ecc. Ecc. Quando i dati arrivano in ingresso.

  5. Utilizzare le stored procedure e / o le query con parametri il più ansible. Evita sql dinamico sia nel codice client db che in sql. (Evita le istruzioni exec con codice dinamico con sezioni esterne nelle stored procedure !!!) La parametrizzazione sfuggirà ai terminatori di stringa come l’apostrofo, le lunghezze dei campi di cattura e la verifica del tipo. Non possiamo sempre fare affidamento sulle API che forniscono la parametrizzazione per essere perfette, ma sono scritte da persone molto più consapevoli delle idiosincrasie del database rispetto alla maggior parte di noi.

  6. Assicurati che non ci siano code vaganti in una directory web leggibile / eseguibile. Se non fa parte del sito attivo, archivialo in un luogo sicuro e cancellalo dalla visualizzazione pubblica. Lo stesso vale per le stored procedure non utilizzate.

  7. Rimani aggiornato sulle API del database. Alcuni modi di eseguire istruzioni SQL in alcune API non sono sicuri come altri.

  8. Archivia le password in modo sicuro con la crittografia unidirezionale. In questo modo, un dump della tabella di nomi utente e password dovrebbe ancora tenere fuori le persone.

  9. Indurisci il server in tutti i soliti modi. Ad esempio, quando ansible, dai privilegi minimi sulle tabelle del database. Limitare l’accesso degli account del database del server Web esclusivamente alle tabelle in questione. Usa solo il più ansible. Crea più account che creano una divisione tra i diritti di accesso del traffico pubblico e in-house / trusted.

  10. Cattura gli errori con grazia. Questo vale per tutto il codice, non solo per il codice che utilizza il database. Gli attacchi Sql injection si basano in particolare sui messaggi di errore e quindi è auspicabile hide il più ansible al pubblico dal database. Scrivi sempre codice che gestisce eccezioni o set di dati vuoti in modo vanilla, in modo da rivelare il meno ansible su quale tipo di database stiamo utilizzando, quali sono i campi nelle nostre tabelle o su che tipo di query stiamo eseguendo. Registra errori sul server. Anche nel codice non di database, è meglio tacere su componenti di terze parti, strutture di cartelle di file, altri servizi che potremmo essere in esecuzione, ecc. Dare agli utenti malati il ​​minimo di informazioni possibili è la chiave per tenerli all’oscuro.

E # 11, rivisita sempre / rivedi questo elenco. Essere sempre aggiornato Sii proattivo. Rendilo priorità e requisito prioritario, non un ripensamento.

Non è necessario alcun algoritmo: non utilizzare la concatenazione di stringhe per creare istruzioni SQL. Utilizzare invece la raccolta SqlCommand.Parameters. Questo fa tutto il necessario escape dei valori (come la sostituzione di ' with '' ) e garantisce che il comando sia sicuro perché qualcun altro (cioè Microsoft) ha eseguito tutti i test.

ad es. chiamando una procedura memorizzata:

 using (var connection = new SqlConnection("...")) using (var command = new SqlCommand("MySprocName", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@Param1", param1Value); return command.ExecuteReader(); } 

Questa tecnica funziona anche per istruzioni SQL inline, ad es

 var sql = "SELECT * FROM MyTable WHERE MyColumn = @Param1"; using (var connection = new SqlConnection("...")) using (var command = new SqlCommand(sql, connection)) { command.Parameters.AddWithValue("@Param1", param1Value); return command.ExecuteReader(); }