Domanda

Abbiamo un'applicazione Java che comunica con più database SQL Server nella stessa casella.Il numero e i nomi di questi database variano.In generale, utilizziamo quasi esclusivamente procedure memorizzate con CallableStatement per accedere ai database.Siamo estremamente bravi nell'evitare l'iniezione SQL e nell'utilizzare variabili di associazione.

L'unica preoccupazione è che il nome del database stesso è concatenato nell'SQL che passiamo a CallableStatement come tale:

"{call [" + dbName + ".dbo." + procName + "(?, ?, ?)}"

procName è codificato in classi figlie utilizzando un modello di metodo modello, in modo che la stringa sia garantita come sicura.

dbName è definito esternamente.Ho provato a impostare dbName su tutti i tipi di pattern per sfuggire alla sintassi e sfruttarlo nel mio ambiente di sviluppo e non ho avuto successo.

L'ho impostato come segue per produrre le seguenti chiamate SQL (nomi di tabelle e proc modificati per proteggere gli innocenti):

securitytest].nx_proc()};delete from poor_victim_table;

diventa

{call [securitytest].nx_proc()};delete from poor_victim_table;].dbo.proper_proc_name()}

E

securitytest].nx_proc()};exec('delete from poor_victim_table');

diventa

{call [securitytest].nx_proc()};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

Risultati in Incorrect syntax near ')'. E poor_victim_table ha ancora righe.ho usato truncate table, drop table E drop database e quando non funzionavano, passavo al semplice delete per escludere le impostazioni di sicurezza.

Se utilizzo un proc che accetta parametri di collegamento, ottengo sempre una mancata corrispondenza tra il numero di parametri previsti e i parametri forniti come The index 1 is out of range..

securitytest]};exec('delete from poor_victim_table');

diventa

{call [securitytest]};exec('delete from poor_victim_table');].dbo.proper_proc_name(?,?,?,?,?,?,?)}

Tutte le strade sembrano portare a un errore di runtime e l'SQL non viene eseguito.Naturalmente, questo è fantastico.Ma voglio assicurarmi che fallisca perché non può riuscire e non fallire perché non riesco a provare la giusta combinazione.

L'opinione popolare/mito urbano è che l'utilizzo di una procedura memorizzata rende immuni all'iniezione SQL, ma preferisco non fidarmi di affermazioni assolute del genere quando si tratta di sicurezza.

Dopo aver effettuato ricerche per un po', la cosa migliore che mi è venuta in mente è questa domanda StackOverflow: SQL injection: nessun pericolo nella chiamata alla procedura memorizzata (su iSeries)?.Sembra supportare l'utilizzo di CallableStatement perché ti protegge dall'iniezione SQL a meno che il codice di procedura stesso non crei SQL dinamico da un parametro di input.

Quindi, la mia domanda alla comunità è, presupponendo che il codice SQL in un proc sia sicuro, l'utilizzo di CallableStatement in JDBC impedisce davvero l'iniezione SQL?Oppure il driver SQL Server analizza la stringa in modo da impedirla, ma altri driver potrebbero non farlo?Oppure non mi sto impegnando abbastanza?

Se è sicuro, come viene fornita tale garanzia?È dovuto alla sintassi astratta dell'utilizzo { call blah(?) } che non è il vero SQL, ma viene tradotto in SQL?

È stato utile?

Soluzione

Voi Dovrebbe sii sicuro, ma proprio come te, non mi fiderei, soprattutto se ti stai interfacciando con database diversi utilizzando driver JDBC diversi, ecc.

Se fossi in te, prima della dichiarazione che hai pubblicato, mi assicurerei di controllare se dbName contiene altro che lettere, cifre e possibilmente un carattere di sottolineatura.Ciò dovrebbe consentire tutti i dbName validi e impedire tutti i tipi di problemi con esso.

Altri suggerimenti

Controlla l'URL della tua connessione db, penso che si riferisca a db statico, quindi se scrivi il nome db nell'istruzione richiamabile questo genererà problemi ogni volta che il nome db cambia, il tuo codice come die (la maggior parte dei posti da cambiare), quindi non usare il nome db nella query ma puoi creare oggetti diversi per connessioni database diverse o classi helper diverse per questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top