Jangan Lakukan Parsing SQL untuk Membuat Query Runner Menjadi Read-Only
Berhentilah mencoba mengamankan database Anda dengan memeriksa kata kunci dalam string SQL.
Jika Anda membangun alat untuk menjalankan SQL, Anda menginginkan mode read-only. Anda ingin mencegah perintah UPDATE yang tidak disengaja menghapus data Anda. Pikiran pertama Anda mungkin adalah memblokir kata-kata seperti DELETE atau DROP.
Jangan lakukan ini.
Pemeriksaan string sangat mudah dilewati. Seorang pengguna dapat menggunakan klausa WITH untuk menyembunyikan DELETE. Mereka dapat menggunakan komentar untuk menyembunyikan perintah. Mereka dapat memanggil fungsi yang menulis ke sebuah tabel. Anda akhirnya terjebak dalam permainan whack-a-mole yang tidak akan pernah menang.
Biarkan database yang menangani keamanan.
Postgres memiliki fitur bawaan untuk hal ini. Anda dapat mendeklarasikan transaksi sebagai read-only. Server kemudian akan menolak perintah tulis apa pun. Ini mencakup CTE, fungsi, dan DDL.
Berikut cara mengimplementasikannya dengan benar di Python:
- Gunakan transaksi nyata dengan mengatur
autocommitkeFalse. - Jalankan
SET TRANSACTION READ ONLYsebagai perintah pertama. - Atur
statement_timeoutuntuk mencegah kueri yang berjalan lama mengunci sistem Anda. - Gunakan
rollback()di akhir untuk melepaskan lock dan snapshot.
Pendekatan ini tidak memeriksa teks SQL. Kueri dikirim ke server persis seperti yang ditulis. Anda memberi tahu mesin untuk menegakkan aturan tersebut.
Keamanan membutuhkan dua bagian:
- Perlindungan dari penulisan: Gunakan transaksi read-only.
- Perlindungan dari penyalahgunaan sumber daya: Gunakan timeout dan batasan baris.
Kueri read-only masih dapat membuat sistem Anda crash dengan join yang masif. Transaksi read-only menghentikan penulisan, tetapi tidak menghentikan penggunaan sumber daya yang berat. Anda membutuhkan keduanya untuk membuat SQL ad-hoc menjadi aman.
Berhentilah melakukan parsing SQL. Mintalah database untuk melakukan tugasnya.
Sumber: https://dev.to/hitoshi1964/dont-parse-sql-to-make-a-query-runner-read-only-b62