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

È stato utile?

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

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