Qualunque database consente di disabilitare le query non parametrizzate e quindi disabilitare l'iniezione SQL?

5

Esiste già un database che lo consente?

In caso contrario, ecco come penso che potrebbe essere fatto. Penso che sarebbe necessario modificare il software del database e il driver o il codice che sta assemblando la query SQL. Credo che a volte questo sia fatto dal database stesso e talvolta dal driver.

Un'impostazione come "Solo parametri sicuri" sarebbe abilitata per l'account utente del database usato dal server web. Se è abilitato, saranno consentiti solo i parametri contrassegnati come sicuri. Il protocollo di rete del database deve avere la capacità del driver di comunicare che i parametri nella query sono stati sostituiti dal driver in modo sicuro e non dal codice chiamante.

L'account utente utilizzato da un amministratore per fare query non avrebbe questa funzione abilitata perché non usiamo query parametrizzate quando si fa amministrazione.

Funzionerebbe? C'è qualcosa che mi manca?

    
posta Sarel Botha 20.12.2012 - 19:45
fonte

4 risposte

7

Non esiste un DBMS che lo faccia.

Il problema principale è che non esiste un modo per un server di database di dire quali parti di una query SQL sono state generate dall'input dell'utente, quindi non c'è modo di impedire le query che sono state formate con l'input dell'utente. Una volta che i tuoi pezzi sono stati aggiunti in una stringa, non puoi separarli per capire cosa è stato più.

Tuttavia, ciò che un DBMS potrebbe forse fare è osservare che la maggior parte dei difetti di SQL injection sono sotto forma di valori letterali:

"SELECT * FROM things WHERE id='"+id+"'"

e vietare ciò escludendo i letterali (almeno stringhe e stringhe) dalle query. Questo sarebbe un po 'scomodo in quanto non sarebbe più possibile scrivere query con valori letterali statici in:

"SELECT * FROM things WHERE id=? AND active=1", id

invece dovresti usare un parametro per ogni cosa:

"SELECT * FROM things WHERE id=? AND active=?", id, 1

Questa sarebbe sicuramente una caratteristica interessante per un DBMS da introdurre come opzione. Tuttavia, non catturerebbe l'input dell'utente utilizzato per altri scopi, ad esempio i nomi delle colonne:

"SELECT * FROM things ORDER BY "+sortcolumn

che accade più spesso di quanto si vorrebbe.

The network protocol of the database must have the ability for the driver to communicate that the parameters in the query were replaced by the driver safely and not by the calling code.

O, meglio, usa un protocollo che trasmette i parametri separatamente al corpo della query. Alcuni DBMS e livelli di accesso ai dati lo fanno, altri no.

    
risposta data 20.12.2012 - 22:41
fonte
3

Sì, c'è qualcosa che ti manca. A meno che non si scriva anche il database per non consentire altro che la clausola dove parametrizzata non funzionerà. Come verrà il database a sapere quando qualcuno sta inviando solo una stringa di query o quando qualcosa viene sottoposto a parametrizzazione? Cosa succede se il software passa solo la query stessa, senza parametri. Ad esempio, il tuo codice utilizza:

sqlcommand = "Select * from users where userid = @id"
parameter p = new parameter(someId)
sqlcommand.parameters.add(p)

Driver o qualsiasi altra cosa può inviare questo al database come:

Select * from users where userid = 1234

    
risposta data 20.12.2012 - 20:40
fonte
3

Analisi del codice statico

Esiste una variante della tua idea che viene utilizzata nella pratica e funziona abbastanza bene secondo la mia esperienza:

Gli strumenti di analisi del codice statico come Findbug possono identificare le invocazioni dei metodi del database (ad es. executeUpdate) con istruzioni SQL che non sono costanti in fase di compilazione.

Non è perfetto: perderà le invocazioni dei metodi del database tramite la riflessione.

Problemi con analisi dopo il fatto

SELECT * FROM sossys WHERE type = 2;

Potrebbe essere una dichiarazione perfettamente codificata. Va bene, si può sostenere che i parametri dovrebbero sempre essere usati anche per le affermazioni non dinamiche.

Si supponga che la seguente istruzione sia inviata al server del database

SELECT * FROM person, account 
WHERE account.person_id = person.id AND person.id=:1

Questa affermazione ha un bell'aspetto. È stato creato da un algoritmo di ricerca che unisce dinamicamente le tabelle pertinenti. In questo caso, è stato ingannato unirsi alla tabella dell'account, con conseguente esposizione degli hash delle password.

A causa della natura di SQL non è possibile utilizzare istruzioni SQL statiche per questo, a meno che il numero di tabelle opzionali sia molto piccolo. L'approccio di analisi del codice statico creerà un avviso per attivare la revisione manuale.

Sommario

Non sono a conoscenza di un database o un driver che impedisce le query create dinamicamente. Il tuo approccio non catturerà tutto, ma probabilmente colpirà gli errori più comuni. Fino a quando non sarà disponibile, gli strumenti di analisi del codice statico sono un'ottima opzione.

    
risposta data 20.12.2012 - 22:31
fonte
2

Non di default.

Ciò che puoi fare è disabilitare l'accesso diretto CRUD a qualsiasi tabella da qualsiasi utente non amministrativo (come gli accessi utilizzati dai tuoi siti Web e software) e invece fornire l'accesso alle operazioni CRUD dando le autorizzazioni EXECUTE su stored procedure specifiche. Questo è il "livello di servizio del povero uomo"; non si può fare nulla se non ciò che una stored procedure consente e quelle stored procedure non devono mai trattare i dati delle variabili di input come comandi in se stessi. Ho visto questo fatto molte volte nell'industria, spesso evitando il nuovo modello ORM.

Ho citato "livello di servizio"; questo è fondamentalmente l'altro modo in cui si blocca un database contro gli attacchi in generale, richiedendo a tutte le richieste di dati di passare attraverso un livello di servizio, che implementa le query effettive in modo impervio all'iniezione (come l'utilizzo di un ORM, che esegue la maggior parte delle istruzioni attraverso sp_executesql, che mantiene tutti i parametri passati separati dal comando effettivo). Funziona nello stesso modo base delle stored procedure, tranne che ora hai una linea aggiuntiva di sicurezza; nulla sul lato client o sul server web deve anche sapere come accedere al database.

    
risposta data 20.12.2012 - 23:25
fonte

Leggi altre domande sui tag