Database
 sql >> डेटाबेस >  >> RDS >> Database

SQL इंजेक्शन के विरुद्ध JDBC एप्लिकेशन की सुरक्षा कैसे करें

अवलोकन

एक रिलेशनल डेटाबेस मैनेजमेंट सिस्टम (RDBMS) में, एक विशिष्ट भाषा होती है - जिसे SQL (स्ट्रक्चर्ड क्वेरी लैंग्वेज) कहा जाता है - जिसका उपयोग डेटाबेस के साथ संचार करने के लिए किया जाता है। SQL में लिखे गए क्वेरी स्टेटमेंट का उपयोग डेटाबेस की सामग्री और संरचना में हेरफेर करने के लिए किया जाता है। एक विशिष्ट SQL स्टेटमेंट जो डेटाबेस की संरचना को बनाता और संशोधित करता है उसे DDL (डेटा डेफिनिशन लैंग्वेज) स्टेटमेंट कहा जाता है और डेटाबेस की सामग्री में हेरफेर करने वाले स्टेटमेंट को DML (डेटा मैनिपुलेशन लैंग्वेज) स्टेटमेंट कहा जाता है। RDBMS पैकेज से जुड़ा इंजन SQL कथन को पार्स और व्याख्या करता है और उसके अनुसार परिणाम देता है। यह RDBMS के साथ संचार की विशिष्ट प्रक्रिया है - एक SQL कथन को फायर करें और परिणाम वापस प्राप्त करें, बस। सिस्टम किसी भी बयान के इरादे का न्याय नहीं करता है जो भाषा की वाक्य रचना और शब्दार्थ संरचना का पालन करता है। इसका अर्थ यह भी है कि यह जांचने के लिए कोई प्रमाणीकरण या सत्यापन प्रक्रिया नहीं है कि कथन किसने चलाया और आउटपुट प्राप्त करने पर किसी के पास विशेषाधिकार है। एक हमलावर केवल दुर्भावनापूर्ण इरादे से एक SQL कथन को आग लगा सकता है और वह जानकारी वापस प्राप्त कर सकता है जिसे उसे प्राप्त नहीं करना चाहिए। उदाहरण के लिए, एक हमलावर वेब एप्लिकेशन के डेटाबेस सर्वर को नियंत्रित करने के लिए हानिरहित दिखने वाली क्वेरी के साथ एक दुर्भावनापूर्ण पेलोड के साथ एक SQL कथन निष्पादित कर सकता है।

यह कैसे काम करता है

एक हमलावर इस भेद्यता का लाभ उठा सकता है और अपने फायदे के लिए इसका इस्तेमाल कर सकता है। उदाहरण के लिए, कोई एप्लिकेशन के प्रमाणीकरण और प्राधिकरण तंत्र को बायपास कर सकता है और संपूर्ण डेटाबेस से तथाकथित सुरक्षित सामग्री को पुनः प्राप्त कर सकता है। डेटाबेस से रिकॉर्ड बनाने, अपडेट करने और हटाने के लिए SQL इंजेक्शन का उपयोग किया जा सकता है। इसलिए, SQL के साथ अपनी कल्पना तक सीमित एक क्वेरी तैयार कर सकता है।

आमतौर पर, एक एप्लिकेशन कई उद्देश्यों के लिए डेटाबेस में SQL क्वेरीज़ को अक्सर सक्रिय करता है, चाहे वह कुछ रिकॉर्ड प्राप्त करने के लिए हो, रिपोर्ट बनाने के लिए, उपयोगकर्ता को प्रमाणित करने के लिए, CRUD लेनदेन के लिए, आदि। हमलावर को बस कुछ एप्लिकेशन इनपुट फॉर्म के भीतर एक SQL इनपुट क्वेरी खोजने की आवश्यकता होती है। तब प्रपत्र द्वारा तैयार की गई क्वेरी का उपयोग दुर्भावनापूर्ण सामग्री को जोड़ने के लिए किया जा सकता है, ताकि जब एप्लिकेशन क्वेरी को सक्रिय करे, तो उसमें इंजेक्टेड पेलोड भी हो।

आदर्श स्थितियों में से एक तब होती है जब कोई एप्लिकेशन उपयोगकर्ता से उपयोगकर्ता नाम या उपयोगकर्ता आईडी जैसे इनपुट मांगता है। एप्लिकेशन ने वहां एक कमजोर स्थान खोल दिया। SQL कथन अनजाने में चलाया जा सकता है। एक हमलावर एक पेलोड को इंजेक्ट करके लाभ उठाता है जिसे SQL क्वेरी के एक भाग के रूप में उपयोग किया जाता है और डेटाबेस द्वारा संसाधित किया जाता है। उदाहरण के लिए, लॉगिन फॉर्म के लिए POST ऑपरेशन के लिए सर्वर-साइड छद्म कोड हो सकता है:

uname = getRequestString("username");
pass = getRequestString("passwd");

stmtSQL = "SELECT * FROM users WHERE
   user_name = '" + uname + "' AND passwd = '" + pass + "'";

database.execute(stmtSQL);

पिछला कोड SQL इंजेक्शन हमले के लिए असुरक्षित है क्योंकि चर 'unname' और 'pass' के माध्यम से SQL कथन को दिए गए इनपुट को इस तरह से हेरफेर किया जा सकता है जो कथन के शब्दार्थ को बदल देगा।

उदाहरण के लिए, हम डेटाबेस सर्वर के विरुद्ध चलाने के लिए क्वेरी को संशोधित कर सकते हैं, जैसा कि MySQL में है।

stmtSQL = "SELECT * FROM users WHERE
   user_name = '" + uname + "' AND passwd = '" + pass + "' OR 1=1";

इसका परिणाम मूल SQL कथन को उस हद तक संशोधित करना है जो किसी को प्रमाणीकरण को बायपास करने में सक्षम बनाता है। यह एक गंभीर भेद्यता है और इसे कोड के भीतर से रोका जाना चाहिए।

SQL इंजेक्शन हमले से बचाव

SQL इंजेक्शन हमले की संभावना को कम करने के तरीकों में से एक यह सुनिश्चित करना है कि पाठ के अनफ़िल्टर्ड स्ट्रिंग्स को निष्पादन से पहले SQL कथन में संलग्न होने की अनुमति नहीं दी जानी चाहिए। उदाहरण के लिए, हम तैयार स्टेटमेंट . का उपयोग कर सकते हैं आवश्यक डेटाबेस कार्यों को करने के लिए। तैयार विवरण . का दिलचस्प पहलू यह है कि यह एक स्ट्रिंग के बजाय डेटाबेस में एक पूर्व-संकलित SQL कथन भेजता है। इसका मतलब है कि क्वेरी और डेटा अलग-अलग डेटाबेस में भेजे जाते हैं। यह SQL इंजेक्शन हमले के मूल कारण को रोकता है, क्योंकि SQL इंजेक्शन में, विचार कोड और डेटा को मिलाना है जिसमें डेटा वास्तव में डेटा की आड़ में कोड का एक हिस्सा है। तैयार विवरण . में , कई हैं setXYZ() विधियाँ, जैसे कि सेटस्ट्रिंग () . इन विधियों का उपयोग विशेष वर्णों को फ़िल्टर करने के लिए किया जाता है जैसे कि SQL कथनों में निहित उद्धरण।

उदाहरण के लिए, हम निम्न तरीके से SQL कथन निष्पादित कर सकते हैं।

String sql = "SELECT * FROM employees WHERE emp_no = "+eno;

डालने के बजाय, कहें, eno=10125 इनपुट में एक कर्मचारी संख्या के रूप में, हम इनपुट के साथ क्वेरी को संशोधित कर सकते हैं जैसे:

eno = 10125 OR 1=1

यह क्वेरी द्वारा दिए गए परिणाम को पूरी तरह से बदल देता है।

एक उदाहरण

निम्नलिखित उदाहरण कोड में, हमने दिखाया है कि कैसे तैयार स्टेटमेंट डेटाबेस कार्यों को करने के लिए इस्तेमाल किया जा सकता है।

package org.mano.example;

import java.sql.*;
import java.time.LocalDate;
public class App
{
   static final String JDBC_DRIVER =
      "com.mysql.cj.jdbc.Driver";
   static final String DB_URL =
      "jdbc:mysql://localhost:3306/employees";
   static final String USER = "root";
   static final String PASS = "secret";
   public static void main( String[] args )
   {
      String selectQuery = "SELECT * FROM employees
         WHERE emp_no = ?";
      String insertQuery = "INSERT INTO employees
         VALUES (?,?,?,?,?,?)";
      String deleteQuery = "DELETE FROM employees
         WHERE emp_no = ?";
      Connection connection = null;
      try {
         Class.forName(JDBC_DRIVER);
         connection = DriverManager.getConnection
            (DB_URL, USER, PASS);
      }catch(Exception ex) {
         ex.printStackTrace();
      }
      try(PreparedStatement pstmt =
            connection.prepareStatement(insertQuery);){
         pstmt.setInt(1,99);
         pstmt.setDate(2, Date.valueOf
            (LocalDate.of(1975,12,11)));
         pstmt.setString(3,"ABC");
         pstmt.setString(4,"XYZ");
         pstmt.setString(5,"M");
         pstmt.setDate(6,Date.valueOf(LocalDate.of(2011,1,1)));
         pstmt.executeUpdate();
         System.out.println("Record inserted successfully.");
      }catch(SQLException ex){
         ex.printStackTrace();
      }
      try(PreparedStatement pstmt =
            connection.prepareStatement(selectQuery);){
         pstmt.setInt(1,99);
         ResultSet rs = pstmt.executeQuery();
         while(rs.next()){
            System.out.println(rs.getString(3)+
               " "+rs.getString(4));
         }
      }catch(Exception ex){
         ex.printStackTrace();
      }
      try(PreparedStatement pstmt =
            connection.prepareStatement(deleteQuery);){
         pstmt.setInt(1,99);
         pstmt.executeUpdate();
         System.out.println("Record deleted
            successfully.");
      }catch(SQLException ex){
         ex.printStackTrace();
      }
      try{
         connection.close();
      }catch(Exception ex){
         ex.printStackTrace();
      }
   }
}

एक झलक तैयार विवरण . में

इन कार्यों को JDBC विवरण के साथ भी पूरा किया जा सकता है इंटरफ़ेस, लेकिन समस्या यह है कि यह कई बार काफी असुरक्षित हो सकता है, खासकर जब डेटाबेस को क्वेरी करने के लिए एक गतिशील SQL कथन निष्पादित किया जाता है जहां उपयोगकर्ता इनपुट मान SQL क्वेरी के साथ संयोजित होते हैं। यह एक खतरनाक स्थिति हो सकती है, जैसा कि हमने देखा है। सबसे सामान्य परिस्थितियों में, विवरण काफी हानिरहित है, लेकिन तैयार विवरण यह दोनों के बीच बेहतर विकल्प प्रतीत होता है। यह डेटाबेस को स्टेटमेंट भेजने में अपने अलग दृष्टिकोण के कारण दुर्भावनापूर्ण स्ट्रिंग्स को संयोजित होने से रोकता है। तैयार विवरण संयोजन के बजाय परिवर्तनीय प्रतिस्थापन का उपयोग करता है। SQL क्वेरी में एक प्रश्न चिह्न (?) रखने का अर्थ है कि एक स्थानापन्न चर अपनी जगह ले लेगा और क्वेरी निष्पादित होने पर मान की आपूर्ति करेगा। प्रतिस्थापन चर की स्थिति setXYZ() में निर्दिष्ट पैरामीटर अनुक्रमणिका स्थिति के अनुसार अपना स्थान लेती है तरीके।

यह तकनीक इसे SQL इंजेक्शन अटैक से बचाती है।

इसके अलावा, तैयार विवरण लागू करता है स्वतः बंद करने योग्य। यह इसे संसाधनों के साथ प्रयास करें . के संदर्भ में लिखने में सक्षम बनाता है जब यह दायरे से बाहर हो जाता है तो ब्लॉक कर देता है और अपने आप बंद हो जाता है।

निष्कर्ष

एक SQL इंजेक्शन हमले को केवल जिम्मेदारी से कोड लिखकर ही रोका जा सकता है। वास्तव में, किसी भी सॉफ्टवेयर समाधान में खराब कोडिंग प्रथाओं के कारण सुरक्षा ज्यादातर भंग हो जाती है। यहां, हमने बताया है कि किन चीजों से बचना चाहिए और कैसे तैयार स्टेटमेंट सुरक्षित कोड लिखने में हमारी मदद कर सकता है। SQL इंजेक्शन पर एक पूर्ण विचार के लिए, उपयुक्त सामग्री देखें; इंटरनेट उनमें से भरा हुआ है, और, तैयार विवरण . के लिए , अधिक विस्तृत स्पष्टीकरण के लिए जावा एपीआई दस्तावेज़ीकरण देखें।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. लॉग बैकअप लॉगिंग को दबाने के लिए ट्रेस फ्लैग 3226 का उपयोग करना

  2. SQL डेटा प्रकारों को समझना - आप सभी को SQL डेटा प्रकारों के बारे में जानना आवश्यक है

  3. पांडा:फाइलें कैसे पढ़ें और लिखें

  4. डेटाबेस के लिए डिस्क स्थान की योजना

  5. सामान्य त्रुटि:OS संस्करण बेमेल