SQL Injection
• Kunto Aji - Last modified atUpdate 2020-05-29: Artikel ini merupakan translasi yang saya buat untuk ASCIIcasts untuk Ruby on Rails versi 2.
Salah satu aturan utama dari security adalah jangan pernah percaya pada input dari seorang user. Dalam Rails, hal ini berarti memperhatikan seluruh item dalam hash params. User dapat mengontrol baik key maupun value dari hash params, sehingga seluruh input harus diwaspadai.
Hal tersebut juga berlaku untuk hash cookies, dimana user dapat mengatur apa yang ada di dalamnya. Sebaliknya, hash session adalah satu-satunya yang berada di sisi server, sehingga dapat dipercaya nilai yang ada pada hash session.
Salah satu masalah umum security adalah SQL Injection. Hal ini terjadi ketika inputan dari user ditempatkan secara langsung dalam sebuah query SQL.
Jika seorang user mengetahui bahwa inputan miliknya langsung dilakukan insert ke dalam sebuah query, secara sengaja mereka dapat menulis input yang dapat mengambil data dari database yang seharusnya tidak boleh terlihat atau bahkan mengubah atau menghapus data dalam database.
Kita akan menjelaskan bagaimana hal ini bekerja dan bagaimana terlindung dari SQL Injection dengan sebuah contoh sederhana.
Pencarian Task
Di bawah ini kita memiliki sebuah form pencarian sederhana pada sebuah halaman yang melakukan pencarian dengan menggunakan SQL LIKE untuk mendapatkan task dengan nama yang cocok dengan input yang diberikan pada form.
Masalahnya adalah input yang diberikan oleh user langsung dikirimkan ke sebuah query database dalam controller kita.
TasksController
diatas menunjukkan SQL query yang berpotensi tidak aman.
Nilai di dalam key :conditions
dalam hash find
yang langsung digunakan sebagai query SQL.
Yang menjadi masalah dengan hal ini adalah jika user mengirimkan parameter yang mengandung sebuah petik tunggal, maka seluruh statement akan dianggap sebagai SQL.
Sehingga jika kita jika sebuah istilah atau kata mengandung sebuah petik tunggal pada saat seach, misal Task 1'TEST
, inputan setelah petik tunggal akan dieksekusi sebagai SQL dan Rails akan melakukan throw error.
SQL tidak valid muncul jika inputan user mengandung petik tunggal.
Dalam perintah SQL diatas yang dimiliki oleh kata dalam search, Task 1'TEST;
dan dari kata tersebut, kita dapat melihat bahwa tanda petik yang ada di dalamnya merupakan statement SQL yang lengkap.
Kemudian, bagian yang terakhir setelah tanda titik koma, TEST%)
, merupakan SQL yang tidak valid yang akan melakukan throw error. Hal ini berbahaya karena dapat menyebabkan SQL apapun dapat dieksekusi dalam database. Bagaimana menghentikan hal ini?
Jawabannya adalah melakukan escape terhadap petik tunggal. Rails memiliki cara yang mudah untuk melakukannya. Kita dapat mengirimkan sebuah array of conditions, di mana di elemen pertamanya merupakan kata yang inputkan saat search dengan value yang digantikan dengan tanda tanya (?).
Setiap tanda tanya dalam elemen pertama akan digantikan oleh value dari dari elemen selanjutnya dalam keadaan telah di-escape, sehingga aman. Jika seandainya kita memiliki tiga buah parameter, maka kita menggunakan tiga buah tanda tanya dan array kita akan memiliki empat buah elemen.
Sintaks diatas adalah cara yang lebih aman untuk mengirimkan sebuah kata dalam search yang di-input oleh user.
Sekarang query kita telah ter-update. Jika kita melakukan search ulang untuk sebuah kata atau istilah dengan petik tunggal didalamnya, Rails akan melakukan escape petik tersebut dengan aman.
Untuk menyakinkan bahwa search menggunakan LIKE
, tanda persen %
perlu ditempatkan dintara query dalam elemen array yang kedua. Menempatkan tanda persen yang mengapit tanda tanya tidak akan membuat query yang menggunakan LIKE
tersebut bekerja.
Kata yang di-search oleh user telah di-escape dengan aman.
Kita dapat melihat sekarang bahwa petik telah di-escape. Sebagai catatan, jika menggunakan SQLite, tanda petik akan di-escape dengan menggunakan dua buah petik tunggal (‘’). Sedangkan database lain biasanya menggunakan backslash \
sebelum tanda petik.
Dalam Rails anda mungkin hanya perlu mengkhawatirkan bagaimana melakukan escape input dalam method find jika anda menggunakan parameter :conditions
. Jika anda menggunakan method dinamis find_by
maka Rails akan secara otomatis melakukan escape terhadap inputan apapun untuk meyakinkan bahwa anda telah aman dari SQL Injection.
Recent Posts
How to Defend Against Brute-Force and DoS Attacks with Fail2ban, Nginx limit_req, and iptables
In this tutorial, I’ll explain how to protect your public-facing Linux server and Nginx web server from common threats, including brute-force and DoS attacks.
Is Getting AWS Solutions Architect Associate Certification Worth It?
If you are a full-time Software Engineer, there's no strong need to pursue this certification.
DevSecOps
My Notes about DevSecOps
AWS Secrets Manager
Explanation about AWS Secrets Manager with example code.
Envelope Encryption
Envelope encryption is the practice of encrypting plaintext data with a data key, and then encrypting the data key under another key.