Vulnerabilità delle iniezioni di SQL durante l'utilizzo dei modelli SQL di Zend Framework


15

Quando si uniscono le tabelle, utilizzo i modelli SQL di Zend Framework. Come esempio ho modificato il mio codice attuale, ma penso che otterrai il punto:

$this->getSelect()->join(
                      array('sections' => $sectionsTableName),
                      'main_table.banner_id = pages.banner_id',
                      array()
                    )
                  ->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
                  ->group('main_table.banner_id'); 

La pagina viene caricata con ajax e il parametro $ section viene inviato come parametro GET ( www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com).

Ora ecco il problema se qualcuno esegue qualcosa del genere:

www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

In questo modo l'utente può scaricare l'intero database. I dati non verranno visualizzati, ma comunque SQL eseguirà il dump che può causare un sovraccarico di SQL.

Domande:

  1. Qual è il modo migliore per prevenire tale scenario?
  2. Ora sono preoccupato per i clienti precedenti. Con questo codice è possibile rendere ancora più rischiose le azioni, come delare o modificare la tabella? Immagino di no perché non è possibile inserire altre istruzioni oltre a SELEZIONA all'interno della sottoselezione, quindi ELIMINA produrrebbe un errore di sintassi di SQL. Ho ragione?

AGGIORNAMENTO: Il mio esempio non è l'illustrazione corretta dell'iniezione SQL perché ci sono 'segno intorno a sezioni $ e quindi non sarà possibile effettuare l'iniezione. In ogni caso ciò sarebbe possibile quando si prevede un valore intero e quando non si filtra l'input intero. Vedi il mio commento qui sotto.


1
Potresti usare: $db = Mage::getSingleton('core/resource')->getConnection('core_read');e $db->quote()anche nel tuo caso guarda $db->quoteInto. Se $thisè una risorsa, si potrebbe fare: $this->getConnection('core_read')->quoteInto()se si tratta di una collezione che si possa fare: $this->getResource()->getConnection('core_read')->quoteInto(). lungo quelle linee. Se questo ti aiuta a raggiungere il tuo obiettivo.
ash

Ho appena realizzato che questo scenario è possibile solo se il valore è intero. Se value è varchar, allora ci sarà sempre 'segno prima di (sign e quindi (SELECTo qualsiasi altra cosa sarà proprio come stringa e non funzione. Quando il campo è intero, 'non è necessario e rende possibile tale scenario. Ma l'intero deve essere sempre filtrato con, intval()quindi anche questo non è un problema.
JohnyFree

E se inizi con la chiusura di '? Quindi ' AND (SELECT ...) '? A proposito, non credo che Zend non stia citando questo ... E se usi i binding, allora il PDO lo gestirà. Non usare mai concatenazioni di punture come questa:"sections.section= '$section'"
ottobre

@ 7ochem in tal caso DEVI legare i parametri usando? e 'diventerà \'. Ma se usi un valore intero, allora non lo devi legare poiché puoi pulirlo usando la funzione php intval () e 'qualcosa diventerà 0.
JohnyFree

Risposte:


8

Convalida il tuo contributo!

Più buono e più che puoi.

Alcuni suggerimenti per la tua convalida:

  1. Controlla la lunghezza della variabile che ottieni tramite il parametro GET. Non è necessario accettare una stringa lunga infinita.

  2. Convalida per un nome di dominio. Che tipo di formato hanno i tuoi nomi di dominio previsti? È sempre www.mydomain.tld? Crea una regex che controlla una corrispondenza o (meglio) usa Zend_Validate_Hostname:

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
  3. Whitelisting: sai quali nomi di dominio aspettarti? È possibile creare un elenco di domini consentiti e confrontarli. Lascia il resto.

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. Inserimento nella blacklist di nomi di dominio e / o caratteri: se ti aspetti un nome di dominio, non è necessario accettare altri caratteri oltre a az e 0-9 e "." (a meno che tu non stia lavorando con nomi di dominio speciali).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.