Sono sicuro contro l'iniezione di SQL
-
06-07-2019 - |
Domanda
Vorrei sapere se sono sicuro contro l'iniezione SQL quando uso qualcosa del genere con PostgresSQL:
CREATE or REPLACE FUNCTION sp_list_name( VARCHAR )
RETURNS SETOF v_player AS '
DECLARE
v_start_name ALIAS FOR $1;
r_player v_player%ROWTYPE;
v_temp VARCHAR;
BEGIN
v_temp := v_start_name || ''%'';
FOR r_player IN
SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
LOOP
RETURN NEXT r_player;
END LOOP;
RETURN;
END;
' LANGUAGE 'plpgsql' VOLATILE;
Voglio usare questa funzione per elencare il nome del giocatore che inizia con una lettera.
select * from sp_list_name( 'A' );
mi dà giocatori con il cognome che inizia con A.
Ho provato a iniettare sql con
select * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );
Sono al sicuro?
In quale caso posso essere iniettato?
Saluti
Soluzione
In termini di procedura sembri sicuro poiché la variabile in SP non verrà espansa in codice, ma puoi comunque esporti se non usi una query con parametri come " SELECT * FROM sp_list_name (?);
" nel tuo codice di moltiplicazione . Qualcosa come " SELECT * FROM sp_list_name ('$ start_name');
" potrebbe essere sovvertito da un utente che passa un nome iniziale di " '); elimina da t_player dove last_name NON IN ('
" ;. Quindi usa una query parametrizzata o un controllo di integrità i tuoi input nel tuo programma.
NB: ad altri, tieni presente che una variabile in una procedura memorizzata non si espanderà nel codice anche se contiene un 'o;, (escluso il passaggio a EXECUTE , per il quale useresti le funzioni quote_literal
, non arrotolate a mano replace
) così sostituendo; o "non è assolutamente necessario (nella procedura memorizzata, l'applicazione che la utilizza è una storia diversa, ovviamente) e ti impedirebbe di trovare sempre " tl; dr
" o " O'Grady
" squadre.
Leo Moore, Karl, LFSR Consulting : v_temp_name
nella procedura memorizzata NOT verrà espanso nel codice in SP (no EXECUTE ), il controllo dovrebbe essere eseguito nell'applicazione, non in SP (o l'OP potrebbe semplicemente utilizzare una query con parametri nel loro codice app). Quello che altri suggeriscono è simile a preoccuparsi di
my $bar = "foo; unlink('/etc/password');";
my $baz = $bar;
eseguendo effettivamente il collegamento in assenza di una valutazione.
Altri suggerimenti
Regola n. 1 per evitare l'iniezione sql: disinfetta tutti gli input che provengono da qualcuno / qualcosa di cui non puoi fidarti / su cui non hai alcun controllo.
Il problema stesso non risiede nel codice del database, ma dall'applicazione che sta eseguendo tali istruzioni.
Il modo corretto di proteggere da SQL Injection è tramite White List * - il lungo e short è impostato sui caratteri che accetti e li filtra.
Il modo errato è Black List - La black list in cui i personaggi non sono accettati è porterà a problemi, perché non puoi stare al passo con gli aggressori. Ci sono modi per aggirare liste nere tramite tabelle ASCII, caratteri di escape e cosa no.
Inoltre, ecco un bel cheat sheet da provare sul tuo sito. Esegui alcuni test e cerca di far fallire le cose.
*
Nell'applicazione, non nel DB (Grazie James)
Non stai generando SQL per te stesso, quindi questo sembra sicuro (per me).
Non so da dove provengano i dati che stai chiamando per la tua procedura memorizzata. Quindi devi ancora proteggerti dagli overflow del buffer ecc.
Ref. Elenco bianco. Questo va bene se vengono seguite alcune altre condizioni. È assolutamente indispensabile suddividere tutti gli input nella sua forma più semplice, quindi non limitarti a cercare nomi di query SQL, virgolette singole ecc. Possono essere rappresentati o codificati utilizzando altri set di caratteri ed è questo che fa parte della lista bianca non specificamente Parole chiave SQL stesse.
Stavo lavorando per un particolare client che consentiva username / password a una risorsa protetta (che alla fine poteva procurarti un pass d'accesso in parti sicure di un aeroporto!). È possibile aggirare il campo di accesso immettendo 'e quindi creando query SQL da lì per recuperare account utente e password.
Il problema era che il cliente aveva già spazzato via £ 200k costruendo il sito con un fornitore che sembrava non aver mai fatto sviluppo web prima. La correzione era di ulteriori £ 60k che era una funzione validata () che stava solo controllando l'unione, selezionare, con parole chiave et al. Alla domanda su cosa hanno fatto per la canicolizzazione / codifica (che ho dovuto poi spiegare) è stato il tempo di ribaltamento.
La casa Dev e il (costoso) Progetto sono stati inscatolati.
Potresti considerare di convalidare il contenuto di
v_start_name. Controlla la stringa per punti e virgola, caratteri di commento, uguali, ecc. Ricorda di controllare sia i caratteri Char che i valori esadecimali. Ricorda di consentire un nome con trattino, ad es. "Smith-Brown" è probabilmente accettabile "Smith - Brown" è potenzialmente un'iniezione.
Se non si ha familiarità con Hex in SQL Injection, le seguenti sono introduzioni rapide
http: // www .arejae.com / blog / SQL-injection-attacco-con-T-SQL-e-hexadecimal.html
http://www.securityfocus.com/infocus/1768
DECLARE v_start_name ALIAS FOR $1; r_player v_player%ROWTYPE; v_temp VARCHAR; BEGIN -- new pseudo code here if v_start_name has bad chars exit with error message -- end pseudo code here v_temp := v_start_name || ''%''; FOR r_player IN SELECT first_name, last_name FROM v_player WHERE last_name like v_temp LOOP RETURN NEXT r_player; END LOOP; RETURN; END;
Saluti Karl
Basta fare una sostituzione su v_start_name per sbarazzarsi di " ;; " ecc. cioè
v_clean_name VARCHAR;
Select v_clean_name = Replace(v_start_name,';','');
Questo sostituirà il; con spazi vuoti che sventano un attacco di iniezione SQL
Per maggiori dettagli vedi Funzioni stringa in PostgresSQL
Come ha anche commentato LFSR Consulting. È meglio WhiteList (ovvero non elaborare alcun input con caratteri non validi come ';') piuttosto che BlackList (ovvero provare a pulire i dati poiché l'utente potrebbe eseguire un attacco di iniezione SQL anche su Sostituisci).
Per maggiori informazioni dai un'occhiata a SQL Injection Attacks