উদাহরণ স্থাপনের জন্য এখানে এসকিউএল রয়েছে:
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);
ইনজেকশন ক্লাসটি এসকিউএল ইঞ্জেকশনের পক্ষে ঝুঁকির মধ্যে রয়েছে। ক্যোরিটি ব্যবহারকারী ইনপুটটির সাথে একত্রে পেস্ট করা হয়েছে। ক্যোয়ারির উদ্দেশ্যটি ছিল বব সম্পর্কে তথ্য প্রদর্শন করা। হয় বেতন বা বোনাস, ব্যবহারকারী ইনপুট উপর ভিত্তি করে। তবে দূষিত ব্যবহারকারী কোথাও একটি 'বা সত্য' এর সমতুল্য হিসাবে পরীক্ষা করে কোয়েরিটিকে দূষিত করে ইনপুটটি পরিচালনা করে যাতে হারান সম্পর্কে যে তথ্য গোপন করা হয়েছিল, সেগুলি সহ সমস্ত কিছু ফিরে আসে।
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"));
}
}
}
এটি চলমান, প্রথম কেসটি সাধারণ ব্যবহারের সাথে এবং দ্বিতীয়টি দূষিত ইনজেকশন সহ:
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
ব্যবহারকারীর ইনপুটটির স্ট্রিং কনটেন্টেশন দিয়ে আপনার এসকিউএল স্টেটমেন্টগুলি তৈরি করা উচিত নয়। এটি কেবল ইনজেকশনের জন্যই ঝুঁকিপূর্ণ নয়, তবে এটি সার্ভারেও ক্যাচিং ইম্পটিকেশনগুলি রয়েছে (বিবৃতি পরিবর্তন হয়, তাই এসকিউএল স্টেটমেন্ট ক্যাশে হিট হওয়ার সম্ভাবনা কম থাকে তবে বাইন্ড উদাহরণটি সর্বদা একই বিবৃতি চালায়)।
এই ধরণের ইনজেকশন এড়ানোর জন্য এখানে বাইন্ডিংয়ের উদাহরণ রয়েছে:
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"));
}
}
}
পূর্ববর্তী উদাহরণের মতো একই ইনপুট দিয়ে এটি চালানো দেখায় যে দূষিত কোডটি কাজ করে না কারণ এই স্ট্রিংয়ের সাথে কোনও পেমেন্টটাইপ মেলে না:
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=?