2012-03-01 18 views
8

devo aggiungere una dichiarazione per il mio programma Java per aggiornare una tabella di database:Prevenire attacchi SQL Injection in un programma Java

String insert = 
    "INSERT INTO customer(name,address,email) VALUES('" + name + "','" + addre + "','" + email + "');"; 

ho sentito che questo può essere sfruttato attraverso un'iniezione SQL come:

DROP TABLE customer; 

Il mio programma ha un'interfaccia grafica Java e tutti i nome, valori di indirizzo ed e-mail vengono recuperati da Jtextfields. Voglio sapere come il seguente codice (DROP TABLE customer;) potrebbe essere aggiunto alla mia dichiarazione di inserimento da parte di un hacker e come posso impedirlo.

+8

obbligatorio [XKCD cartone animato] (http://xkcd.com/327/) – DNA

+1

possibile duplicato del [Java - stringa di escape per prevenire l'SQL injection] (http://stackoverflow.com/questions/1812891/java-escape-string-to-prevent-sql-injection) – Nate

risposta

17

è necessario utilizzare PreparedStatement. ad es.

String insert = "INSERT INTO customer(name,address,email) VALUES(?, ?, ?);"; 
PreparedStatement ps = connection.prepareStatement(insert); 
ps.setString(1, name); 
ps.setString(2, addre); 
ps.setString(3, email); 

ResultSet rs = ps.executeQuery(); 

Ciò impedirà gli attacchi di iniezione.

Il modo in cui l'hacker mette in c'è se la stringa si sta inserendo è venuto da qualche parte in ingresso - per esempio un campo di input su una pagina Web o un campo di input su un modulo in un'applicazione o simile.

7

È possibile controllare THIS articolo per informazioni su questo! :)

mi raccomando con parametri query:

String selectStatement = "SELECT * FROM User WHERE userId = ? "; 
PreparedStatement prepStmt = con.prepareStatement(selectStatement); 
prepStmt.setString(1, userId); 
ResultSet rs = prepStmt.executeQuery(); 
5

Un utente malintenzionato deve immettere qualcosa come '[email protected]"); DROP TABLE customer; nel campo email e il gioco è fatto.

È possibile evitare questo utilizzando la fuga adeguata per dichiarazioni JDBC.

2

Ecco perché si dovrebbe utilizzare punti interrogativi nelle istruzioni di stringa:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES 
            SET SALARY = ? WHERE ID = ?"); 
    pstmt.setBigDecimal(1, 153833.00) 
    pstmt.setInt(2, 110592) 

Citato da here

12

Voglio sapere come questo tipo pezzo di codice ("cliente DROP TABLE;") possono essere aggiunto alla mia dichiarazione di inserimento da un hacker

ad esempio:

name = "'); DROP TABLE customer; --" 

sarebbe cedere questo valore in inserto:

INSERT INTO customer(name,address,email)  VALUES(''); DROP TABLE customer; --"','"+addre+"','"+email+"'); 

io specialmente vorrei sapere come posso impedire questo

Usa istruzioni preparate e argomenti SQL (esempio "rubati "da Matt Fellows):

String insert = "INSERT INTO customer(name,address,email) VALUES(?, ?, ?);"; 
PreparedStament ps = connection.prepareStatment(insert); 

parsing anche i valori che avete a tali variabili e assicurarsi che non contengano caratteri non consentito (ad esempio "" in un nome).

+0

Sto usando una GUI. La persona può inserire solo valori attraverso campi di testo. Come possono aggiungere questo pezzo di codice alla mia statenment. in questo modo INSERISCI NEL VALORE (nome, indirizzo, email) del cliente (''); Cliente DROP TABLE; - "','" + addre + "','" + email + "'); – Grant

+2

Perché non dovresti inserire *'); DROP TABLE cliente; - * in un campo di testo? E comunque, un utente malintenzionato può modificare le limitazioni dei campi di testo (ad esempio, modificare direttamente la RAM, iniettare pacchetti di rete falsificati, ecc ...) – m0skit0

+0

OK. Ho ottenuto il punto.Thönk! – Grant

0

Go per PreparedStatement Vantaggi di un PreparedStatement:

precompilazione e caching DB-lato l'istruzione SQL porta ad esecuzione complessiva più veloce e la possibilità di riutilizzare la stessa istruzione SQL in lotti.

Prevenzione automatica degli attacchi di SQL injection incorporando l'escape di virgolette e altri caratteri speciali. Si noti che ciò richiede l'utilizzo di uno qualsiasi dei metodi SetXxx() PreparedStatement per impostare il valore

1

Come spiegato in this post, lo PreparedStatement da solo non aiuta se si concatenano ancora Stringhe.

Per esempio, un attaccante canaglia può ancora effettuare le seguenti operazioni:

  • chiamata di una funzione di sonno in modo che tutte le connessioni di database saranno impegnati, rendendo quindi l'applicazione disponibile
  • estrazione di dati sensibili dal DB
  • bypassing the user authentication

e non si tratta solo di SQL, ma JPQL e HQL può essere compromessa se non si utilizza parametri legano:

PreparedStatement ps = connection.prepareStatement(
    INSERT INTO customer(name,address,email) VALUES(?, ?, ?) 
); 
int index = 0; 
ps.setString(++index, name); 
ps.setString(++index, address); 
ps.setString(++index, email); 

ResultSet rs = ps.executeQuery(); 

Linea di fondo, non si dovrebbe mai usare la concatenazione di stringhe per la costruzione di istruzioni SQL. Utilizzare un'API dedicata a tale scopo:

Problemi correlati