2009-12-01 8 views
5

Il mio partner su un progetto PHP si oppone alla mia pratica di disinfettare sempre i valori interi in SQL dinamico. Usiamo query parametriche quando possibile. Ma per le condizioni UPDATE e DELETE Zend_Db_Adapter è necessaria una stringa SQL non parametrizzata. È per questo che, anche senza pensare, sempre scrivere qualcosa come:È OK consentire SQL a volte dinamico senza disinfezione?

$db->delete('table_foo', 'id = ' . intval($obj->get_id())); 

che è equivalente, ma è una versione più breve di (ho controllato il codice sorgente ZF):

$db->delete('table_foo', $db->qouteInto('id = ?', $obj->get_id(), 'INTEGER')); 

mio compagno obietta fortemente questo intval(), dicendo che se l'ID $obj è nullo (l'oggetto non è ancora stato salvato nel DB), non noterò un errore e l'operazione DB verrà eseguita silenziosamente. Questo è ciò che gli è realmente accaduto.

Dice che se disinfettiamo tutti i moduli HTML immessi, non è possibile che un ID intero possa entrare in '; DROP TABLE ...' o ' OR 1 = 1 'o un altro valore sgradevole e venga inserito nelle nostre query SQL. Quindi, sono solo paranoico e sto rendendo le nostre vite inutilmente più complicate. "Smetti di fidarti dei valori $_SESSION quindi" dice.

Tuttavia, per le condizioni di valore stringa di lui non è d'accordo con:

$db->update->(
    'table_foo', 
    $columns, 
    'string_column_bar = ' . $db->qoute($string_value)) 
); 

non sono riuscito a dimostrare che aveva torto, e non è riuscito a dimostrare che mi sbaglio. Puoi fare entrambi?

+1

Dichiarazioni parametrate! Dichiarazioni parametrate! Dichiarazioni parametrate! http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – Cheekysoft

+0

@Cheekysoft Signore, avete letto attentamente la domanda? Usiamo dichiarazioni parametrizzate. Invia il tuo mantra a Zend :) –

+1

Wow! Sembra che tu possa associare in delete e update: http://stackoverflow.com/questions/1845153/zend-framework-how-to-delete-a-table-row-where-multiple-things-are-true –

risposta

7

Che si considerano più problemi:

  • Avendo a rintracciare un bug che non ha causato una query SQL fallito.
  • Dover ripristinare i dati dopo aver commesso un errore nel sanitizzare l'input del modulo e qualcuno lo sfrutta.

Qualunque sia la scelta, c'è la tua risposta. Personalmente, tendo ad inclinarmi anche al lato paranoico delle cose.

In caso contrario, è possibile eseguire entrambe le operazioni: creare la propria funzione che prima verifica la presenza di null e quindi chiama intval() e la utilizza invece. Allora ottieni il meglio da entrambi i mondi.

10

Francamente, il tuo partner è fuori dal rocker: l'igienizzazione è economica, non ci sono buone ragioni per non farlo. Anche se si sta disinfettando ciò che è nei moduli HTML, se tali controlli si interrompono in qualche modo sulla produzione, sarete felici di avere un backup in altri luoghi. Inoltre, promuove una buona pratica.

Si dovrebbe sterilizzare — sempre

0

ingresso modulo deve IDD sempre essere sterilizzata, ma non ogni variabile che va in una query deve essere sterilizzata imo ...
L'origine della variabile gioca un ruolo significativo qui .

Devi solo sapere se i dati utilizzati si può fidare ...

0

Se si guarda più in profondità all'interno del codice del framework Zend, vedrai che $ DB-> quoteInto() si trasforma in $ db- > citazione che restituisce (stringa) intval (valore $) con INTEGER come tipo.

Se il tipo non è definito, viene chiamato $ db -> _ quote(). Il suo codice è la seguente:

protected function _quote($value) 
{ 
    if (is_int($value) || is_float($value)) { 
     return $value; 
    } 
    return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'"; 
} 

Qualunque sia il metodo chiamante utilizzato (con o senza specificare il tipo), $ db-> Elimina è totalmente sicuro.

+0

Doesn ' t importa delete() con quoteInto (... 'INTEGER') inietta silenziosamente null comunque. –

0

È necessario innanzitutto verificare che l'ID non sia nullo. Se lo è, sai di non fare una query inutile e di continuare da lì. Non ha senso rintracciare i problemi leggendo query SQL non riuscite o così.

3

Penso che il vostro partner è sbagliato - non sta prendendo in considerazione la separazione degli interessi tra i dati sanatisation nel modello (dove vive il codice DB) e dati validazione delle vostre forme.

Normalmente la logica di convalida del modulo si troverà in un'area separata dell'applicazione sul modello. Cioè quando si aggiungono i validatori per formare gli elementi, e questo è spesso fatto nella classe del modulo stesso. Lo scopo di questo livello di codice di convalida è quello di convalidare l'input del modulo e restituire i messaggi appropriati se c'è qualcosa di sbagliato.

Quindi penso che la sanitizzazione dei dati nel modello debba essere considerata separatamente, in quanto il modello è davvero una classe autonoma - e quindi dovrebbe essere responsabile della propria sanificazione dei dati. Poiché in teoria dovresti essere in grado di riutilizzare questo modello altrove nella tua applicazione, il modello non dovrebbe quindi presumere che la sanificazione sia stata effettuata altrove, cioè come parte del livello di validazione del modulo.

Il punto principale dei partner per non notare le query SQL non riuscite in realtà non è un problema nella pratica: è meglio codificare in modo difensivo.

0

Tutti i dati recuperati da un modulo devono essere disinfettati. Nessuna eccezione. Tutti i dati recuperati dal tuo sistema dovrebbero essere già stati disinfettati prima di essere introdotti nel tuo sistema, e quindi non dovrebbero essere disinfettati quando vengono recuperati dal sistema.

Quindi, la domanda è: da dove viene questo intero?

1

Si dovrebbe naturalmente sempre disinfettare e non fare affidamento su moduli HTML. Cosa succede se modifichi il tuo codice e riutilizzi quella parte con altri dati, non provenienti dal modulo HTML ma dal webservice o dall'email o da qualsiasi altra fonte che decidi di aggiungere un anno dopo? L'uso di intval() qui sembra andare bene.

Problemi correlati