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

SQL इंजेक्शन की भेद्यता और Oracle में इसकी रोकथाम को प्रदर्शित करने के लिए एक उदाहरण

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

प्रदर्शन SCOTT स्कीमा की EMP तालिका पर आधारित है। SCOTT स्कीमा स्क्रिप्ट डाउनलोड करने के लिए निम्न लिंक पर क्लिक करें स्कॉट स्कीमा स्क्रिप्ट डाउनलोड करें।

SQL इंजेक्शन करने का एक उदाहरण

इस खंड में, मैं एक पीएल/एसक्यूएल संग्रहीत प्रक्रिया का एक उदाहरण दे रहा हूं जो उस कर्मचारी के वेतन को प्रदर्शित करने के लिए एक पैरामीटर कर्मचारी संख्या (p_empno) के रूप में स्वीकार करेगा। कोड में, मैं REF CURSOR के लिए SQL कथन स्ट्रिंग में उस पैरामीटर (p_empno) मान के संयोजन का उपयोग कर रहा हूं, जो अनुशंसित नहीं है और सफल SQL इंजेक्शन का कारण होगा। नीचे की प्रक्रिया है:

CREATE OR REPLACE PROCEDURE PRC_GET_EMP_SAL (p_empno VARCHAR2)
IS
   --Declare a ref cursor and local variables--
   TYPE C IS REF CURSOR;

   CUR_EMP   C;
   L_ENAME   VARCHAR2 (100);
   L_SAL     NUMBER;
   L_STMT    VARCHAR2 (4000);
BEGIN
   --Open the ref cursor for a Dynamic SELECT statement--
   L_STMT := 'SELECT ename, sal 
            FROM emp 
            WHERE empno = ''' || p_empno || '''';

   OPEN CUR_EMP FOR L_STMT;

   LOOP
      --Fetch the result set and print the result set--
      FETCH CUR_EMP
      INTO L_ENAME, L_SAL;

      EXIT WHEN CUR_EMP%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (L_ENAME || ' -- ' || L_SAL);
   END LOOP;

   CLOSE CUR_EMP;
END;
/

अब हम उपरोक्त प्रक्रिया का सामान्य रूप से परीक्षण करेंगे एक कर्मचारी संख्या पास करके।

परीक्षा

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal ('7566');
END;
/

आउटपुट

JONES -- 27706.89
PL/SQL procedure successfully completed.

अब तक सब ठीक है। क्योंकि हमने प्रक्रिया को सही ढंग से बुलाया। अब हम देखेंगे कि कैसे हम सभी कर्मचारियों का वेतन प्राप्त करने के लिए SQL इंजेक्शन ट्रिक का उपयोग करके उपरोक्त प्रक्रिया को हैक कर सकते हैं। हो सकता है कि कभी-कभी आप भी ऐसा करना चाहें। मज़ाक!

SQL इंजेक्शन का उपयोग करके परीक्षण करें

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal ('X'' OR ''1''= ''1');
END;
/

सफल SQL इंजेक्शन आउटपुट

WARD -- 11641.56
JONES -- 27706.89
MARTIN -- 11641.56
BLAKE -- 26542.7
CLARK -- 22817.41
SCOTT -- 83819.06
KING -- 46566.18
TURNER -- 13969.85
ADAMS -- 10244.6
JAMES -- 8847.64
FORD -- 27939.74
MILLER -- 12107.2
PL/SQL procedure successfully completed.

वाह, अब आप इस SQL ​​Injection ट्रिक का उपयोग करके प्रत्येक कर्मचारी का वेतन देख सकते हैं। ज़रा सोचिए, कि आपके पास किसी एप्लिकेशन में एक टेक्स्ट फ़ील्ड है चाहे वह ब्राउज़र-आधारित हो या डेस्कटॉप और आप सीधे प्रक्रिया के लिए मान पास कर रहे हैं, और यदि आप उपरोक्त ट्रिक का उपयोग करते हैं, तो निश्चित रूप से ऐसा होगा।

एसक्यूएल इंजेक्शन को रोकने के लिए एक उदाहरण

अब हम पैरामीटर मान को संयोजित करने के बजाय बाइंड वैरिएबल का उपयोग करने के लिए उपरोक्त प्रक्रिया को संशोधित करेंगे और इस तरह कोई SQL इंजेक्शन ट्रिक काम नहीं कर सकती है।

CREATE OR REPLACE PROCEDURE PRC_GET_EMP_SAL_2 (p_empno VARCHAR2)
IS
   --Declare a ref cursor and local variables--
   TYPE C IS REF CURSOR;

   CUR_EMP   C;
   L_ENAME   VARCHAR2 (100);
   L_SAL     NUMBER;
   L_STMT    VARCHAR2 (4000);
BEGIN
   --Open the ref cursor for a Dynamic SELECT statement--
   L_STMT := 'SELECT ename, sal 
            FROM emp 
            WHERE empno = :p_bind_empno';

   OPEN CUR_EMP FOR L_STMT USING p_EMPNO;

   LOOP
      --Fetch the result set and print the result set--
      FETCH CUR_EMP
      INTO L_ENAME, L_SAL;

      EXIT WHEN CUR_EMP%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (L_ENAME || ' -- ' || L_SAL);
   END LOOP;

   CLOSE CUR_EMP;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('Can not fetch any records for: ' || p_empno);
END;
/

उपरोक्त प्रक्रिया का सामान्य रूप से परीक्षण करें

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal_2 ('7566');
END;
/

आउटपुट

JONES -- 27706.89
PL/SQL procedure successfully completed.

SQL इंजेक्शन का उपयोग करके उपरोक्त प्रक्रिया का परीक्षण करें

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal_2 ('1'' OR ''1''= ''1');
END;
/

असफल SQL इंजेक्शन आउटपुट

Can not fetch any records for: 1' OR '1'= '1
PL/SQL procedure successfully completed.

इसलिए इसे नोट कर लें, यदि आप डायनेमिक SQL का उपयोग करके PL/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. एक स्ट्रिंग कैसे सम्मिलित करें जिसमें एक &शामिल है

  2. Oracle में एक स्ट्रिंग को कैसे विभाजित करें

  3. SQLAlchemy के साथ Oracle सेवा नामों का उपयोग करना

  4. Oracle में REPLACE () फ़ंक्शन

  5. Oracle क्वेरी में XMLType नोड्स को संयोजित करें