È sicuro concatenare variabili di sessione non di input in una stringa SQL?

1

Ho un'applicazione php in cui la funzione "makeSessionVar" crea una variabile di sessione dai dati definiti dall'applicazione, quindi la concatena nella stringa SQL.

function makeSessionVar($A,$B){ // (<id>, <sql column name>); 
    ...
    $_SESSION['col'.$A] = $B;
    ...
}

makeSessionVar("1", "dateModified"); 
makeSessionVar("2", "title");
makeSessionVar("3", "notes");

$editSQL = "UPDATE myTable SET " . $_SESSION['col1'] . " = ?,  " . $_SESSION['col2'] . " = ?,  " . $_SESSION['col3']. " = ? WHERE ID = ?";

La mia comprensione è che la concatenazione è pericolosa per i dati definiti dall'utente, ma c'è un modo per un utente finale di avvelenare queste variabili di sessione per iniettare codice arbitrario, o è sicuro?

Sì, so che il modo giusto è quello di fare una dichiarazione completamente preparata è come questa di seguito, ma sono più interessato a sapere se effettivamente conta da un punto di vista della sicurezza.

$editSQL = "UPDATE myTable SET ? = ?,  ? = ?,  ? = ? WHERE ID = ?"
    
posta Nosajimiki 12.10.2018 - 19:30
fonte

1 risposta

5

Supponendo che le query preparate siano facili da usare e non causino problemi di prestazioni qui, allora dovresti semplicemente usare le query preparate. A parità di condizioni, preferisco fare le cose in modo sicuro per impostazione predefinita. In altre parole, invece di chiedere "Dovrei farlo in modo sicuro?" (che è quello che stai chiedendo) prova ad avvicinarti dalla prospettiva opposta: "C'è qualche ragione non per farlo in modo sicuro?". A meno che tu non abbia una buona ragione per farlo senza domande preparate, usale sempre.

Per le variabili di sessione penso che sia particolarmente importante usare sempre le query preparate, perché la loro natura rende facile perdere traccia di dove provengono. È vero che dato il tuo caso d'uso corrente non esiste il rischio immediato di una vulnerabilità di SQL injection (ma nota che i dati di sessione e i dati dei cookie possono essere facilmente confusi e questi ultimi non sono sicuri). Tuttavia le esigenze aziendali cambiano spesso e questo può generare un grande rischio quando la creazione di dati non è facilmente "visibile" da dove viene utilizzata. Cosa succede se nella prossima iterazione dell'applicazione uno di questi pezzi di dati viene ora dall'input dell'utente? Probabilmente ti ricorderai di convertire la tua query in una query preparata quando prima memorizzi l'input dell'utente. Ma ti ricorderai di seguire gli stessi dati attraverso tutta la tua applicazione e assicurarti di non usarlo senza query preparate in un secondo momento? Se si finisce per inserire i dati nel database in modo sicuro, ma in seguito recuperare i dati dal database e utilizzarli in un'altra query non sicura, si può comunque finire con una vulnerabilità di SQL injection.

Quindi non chiedere "Dovrei usare le query preparate?". Comincia invece dall'altra parte: "C'è una ragione per cui non dovrei usare le query preparate?". Se non si dispone di un valido motivo per saltare le query preparate, quindi utilizzarle. Se ritieni di avere una buona ragione per farlo in modo insicuro, allora almeno sei un buon punto di partenza per un'analisi approfondita costi / benefici.

Query preparate con nomi di colonne variabili

Tieni presente che questa sintassi non è effettivamente consentita per le query preparate:

$editSQL = "UPDATE myTable SET ? = ?, ? = ?, ? = ? WHERE ID = ?"

I nomi delle colonne non possono essere forniti con segnaposto. Di conseguenza, in realtà non è possibile creare query preparate come questa. Invece devi fornire i nomi delle colonne come variabili nella costruzione della query, il che significa che può essere vulnerabile alle vulnerabilità di SQLi. Pertanto, il modo in cui ti protegge da SQLi in casi come questo è whitelist il contenuto della variabile per assicurarti che sia esattamente qualcosa che dovrebbe essere.

    
risposta data 12.10.2018 - 20:23
fonte

Leggi altre domande sui tag