L'applicazione è vulnerabile a una seria classe di problemi di sicurezza denominata SQL injection. Vedi http://bobby-tables.com/.
Certo, O'Brian
causa un errore, ma che dire di ');DROP SCHEMA public;--
? O ');DELETE FROM users;--
? Il primo non dovrebbe funzionare perché la tua app deve mai eseguita come superutente o utente che possiede le tabelle, ma pochi progettisti di applicazioni si sforzano di farlo realmente e spesso eseguono utenti privilegiati nella produzione. Il 2 funzionerà nella maggior parte delle applicazioni; vedere la fine del post per i dettagli.
La misura preventiva più semplice e migliore è quello di utilizzare dichiarazioni con parametri* nella tua libreria client. Vedere this example per Delpi:
To use a prepared statement, do something like this:
query.SQL.Text := 'update people set name=:Name where id=:ID';
query.Prepare;
query.ParamByName('Name').AsString := name;
query.ParamByName('ID').AsInteger := id;
query.ExecSQL;
(non ho mai usato Delphi e ultimo scritto il codice Pascal nel 1995, sto solo citando l'esempio dato).
Quello che si sta facendo attualmente è interpolazione stringa di parametri. È molto pericoloso. Può essere fatto in sicurezza solo se si dispone di una funzione robusta per che cita letterali SQL, uno che non si limita a virgolette su ciascuna estremità, ma gestisce anche altre fughe, virgolette doppie, ecc. È l'approccio di ultima istanza; è fortemente preferibile utilizzare una dichiarazione parametrizzata.
Ecco un'espansione dell'esempio che ho dato sopra. Diciamo che si sta facendo un inserto perfettamente normale di un utente per nome utente, dove 'Fred' è un esempio di input nome utente da parte del cliente:
INSERT INTO users (user_name) VALUES ('Fred');
Ora qualche persona sgradevole invia il nome utente ');DELETE FROM users;--
. Improvvisamente l'applicazione viene eseguita:
INSERT INTO users (user_name) VALUES ('');DELETE FROM users;--');
che quando espanso è:
INSERT INTO users (user_name) VALUES ('');
DELETE FROM users;
--');
o in altre parole un inserto che inserisce una stringa vuota (anche se potrebbe facilmente mettere un nome utente perfettamente valido) , seguito da una dichiarazione DELETE FROM users;
- eliminazione di tutte le righe in users
- quindi un commento che non fa nulla. Splat. Ecco i tuoi dati.
* statemments parametrizzati sono a volte indicato erroneamente come istruzioni preparate.Ciò non è corretto perché un'istruzione preparata non è necessariamente parametrizzata e un'istruzione parametrizzata non è necessariamente preparata. La confusione è sorta perché le interfacce database di molti linguaggi non forniscono un modo per utilizzare istruzioni parametrizzate senza utilizzare anche istruzioni preparate.
È possibile utilizzare la funzione 'QuotedStr' (provare a sql-iniettare che ...) – kobik