İşte bir örnek oluşturmak için SQL:
CREATE TABLE employee(name varchar, paymentType varchar, amount bigint);
INSERT INTO employee VALUES('Aaron', 'salary', 100);
INSERT INTO employee VALUES('Aaron', 'bonus', 50);
INSERT INTO employee VALUES('Bob', 'salary', 50);
INSERT INTO employee VALUES('Bob', 'bonus', 0);
Inject sınıfı SQL enjeksiyonuna karşı savunmasızdır. Sorgu, kullanıcı girdisi ile birlikte dinamik olarak yapıştırılır. Sorgunun amacı Bob hakkında bilgi göstermekti. Kullanıcı girişlerine göre maaş veya ikramiye. Ancak kötü niyetli kullanıcı, gizli olması gereken Aaron hakkında bilgiler de dahil olmak üzere her şeyin döndürülmesi için, sorgunun bozulmasına neden olan girdiyi, burada bulunan cümleye eşdeğer bir 'veya true' değerine takarak değiştirir.
import java.sql.*;
public class Inject {
public static void main(String[] args) throws SQLException {
String url = "jdbc:postgresql://localhost/postgres?user=user&password=pwd";
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
String sql = "SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType='" + args[0] + "'";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getString("paymentType") + " " + rs.getLong("amount"));
}
}
}
Bunu çalıştırırken, ilk vaka normal kullanımda, ikincisi kötü amaçlı enjeksiyonda:
c:\temp>java Inject salary
SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType='salary'
salary 50
c:\temp>java Inject "salary' OR 'a'!='b"
SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType='salary' OR 'a'!='b'
salary 100
bonus 50
salary 50
bonus 0
SQL deyimlerini kullanıcı girdisinin dize birleştirmesiyle oluşturmamalısınız. Yalnızca enjeksiyona karşı savunmasız olmakla kalmaz, aynı zamanda sunucu üzerinde de önbellekleme etkileri vardır (ifade değişir, bind örneği her zaman aynı ifadeyi çalıştırırken SQL deyimi önbellek isabetine sahip olma olasılığı daha düşüktür).
İşte bu tür bir enjeksiyondan kaçınmak için bir Bağlama örneği:
import java.sql.*;
public class Bind {
public static void main(String[] args) throws SQLException {
String url = "jdbc:postgresql://localhost/postgres?user=postgres&password=postgres";
Connection conn = DriverManager.getConnection(url);
String sql = "SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType=?";
System.out.println(sql);
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, args[0]);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("paymentType") + " " + rs.getLong("amount"));
}
}
}
Bunu bir önceki örnekle aynı girdi ile çalıştırmak, bu dizeyle eşleşen bir ödeme türü olmadığından kötü amaçlı kodun çalışmadığını gösterir:
c:\temp>java Bind salary
SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType=?
salary 50
c:\temp>java Bind "salary' OR 'a'!='b"
SELECT paymentType, amount FROM employee WHERE name = 'bob' AND paymentType=?