Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Contoh untuk Mendemonstrasikan Kerentanan SQL Injection dan Pencegahannya di Oracle

Kita semua tahu, bahwa jika ada kode aplikasi yang ditulis dengan buruk, maka siapa pun dapat meretas informasi tersebut dengan menggunakan sedikit trik seperti SQL Injection. Dalam posting ini, saya memberikan contoh untuk mendemonstrasikan bagaimana SQL Injection dapat menjadi rentan terhadap suatu aplikasi dan bagaimana Anda dapat mencegahnya.

Demonstrasi didasarkan pada tabel EMP skema SCOTT. Untuk mengunduh skrip skema SCOTT, klik tautan berikut Unduh Skrip Skema Scott.

Contoh Melakukan SQL Injection

Pada bagian ini, saya memberikan contoh prosedur tersimpan PL/SQL yang akan menerima parameter nomor karyawan sebagai (p_empno) untuk menampilkan gaji karyawan tersebut. Dalam kode, saya menggunakan rangkaian nilai parameter (p_empno) itu dalam string pernyataan SQL untuk REF CURSOR, yang tidak direkomendasikan dan akan menjadi penyebab SQL Injection berhasil. Berikut adalah prosedurnya:

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;
/

Sekarang kita akan menguji prosedur di atas secara normal dengan memberikan nomor karyawan.

Uji

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal ('7566');
END;
/

Keluaran

JONES -- 27706.89
PL/SQL procedure successfully completed.

Sampai sekarang semuanya baik-baik saja. Karena kami benar menyebut prosedurnya. Sekarang kita akan melihat bagaimana kita dapat meretas prosedur di atas dengan menggunakan trik SQL Injection untuk mengambil gaji semua karyawan. Mungkin terkadang Anda juga ingin melakukan ini. Bercanda!

Uji Menggunakan SQL Injection

SET SERVEROUTPUT ON;

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

Keluaran Injeksi SQL Berhasil

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.

Wow, sekarang Anda bisa melihat gaji setiap karyawan menggunakan trik SQL Injection ini. Bayangkan saja, bahwa Anda memiliki bidang teks dalam aplikasi apakah itu berbasis browser atau desktop dan Anda memberikan nilai langsung ke prosedur, dan jika Anda menggunakan trik di atas, maka ini pasti akan terjadi.

Contoh untuk Mencegah Injeksi SQL

Sekarang kita akan memodifikasi prosedur di atas untuk menggunakan variabel bind alih-alih menggabungkan nilai parameter dan dengan cara ini tidak ada trik Injeksi SQL yang dapat bekerja.

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;
/

Uji prosedur di atas secara normal

SET SERVEROUTPUT ON;

BEGIN
   prc_get_emp_sal_2 ('7566');
END;
/

Keluaran

JONES -- 27706.89
PL/SQL procedure successfully completed.

Uji prosedur di atas menggunakan SQL Injection

SET SERVEROUTPUT ON;

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

Keluaran Injeksi SQL Gagal

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

Jadi perhatikan, jika Anda membuat program PL/SQL menggunakan SQL dinamis, gunakan metode binding.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ubah stempel waktu menjadi tanggal di Oracle SQL

  2. Konversikan tanggal String ISO-8601 ke tipe data stempel waktu Oracle

  3. Contoh kueri MySQL dengan jawaban

  4. Bagaimana Cara Membuat Paket di Oracle SQL Developer?

  5. Apa operator rangkaian string di Oracle?