Bagaimana cara melindungi data dalam tabel SQL?

Sep 30 2020

Terinspirasi oleh banyaknya kebocoran data di mana seluruh database / tabel dengan informasi pengguna pribadi dibocorkan, apa praktik terbaik untuk melindungi aset tersebut? Saya sangat prihatin jika seseorang bisa mendapatkan akses ke kode backend (yang seharusnya tidak demikian) dan karena itu memperoleh kredensial SQL.

Saya menyimpan data akun pribadi yang hanya perlu diakses oleh pengguna terkait.

Ide saya adalah mengenkripsi data tabel secara simetris dengan nama pengguna dan kata sandi pengguna. Ini membuatnya sangat sulit ketika menangani pengaturan ulang kata sandi ...

Apakah ada ide lain atau implementasi umum untuk skenario ini?

Jawaban

3 Sjoerd Sep 30 2020 at 15:33

Saya sangat prihatin jika seseorang bisa mendapatkan akses ke kode backend dan karena itu memperoleh kredensial SQL.

Sistem database harus dapat diakses dari sejumlah sistem. Secara khusus, ini seharusnya tidak dapat diakses dari internet. Jika seseorang memiliki kredensial SQL, mereka masih tidak akan memiliki akses ke server.

Sumber kebocoran yang umum adalah:

  • Injeksi SQL
  • Server tidak terautentikasi terpapar, seperti MongoDB, ElasticSearch
  • Ekspor CSV atau dokumen yang diekspos, misalnya melalui Google Drive
  • Buka bucket Amazon S3
  • Eksfiltrasi data setelah diretas

Ide saya adalah mengenkripsi data tabel secara simetris dengan nama pengguna dan kata sandi pengguna.

Sebagian besar aplikasi web memiliki teks biasa datanya dalam database, dan cukup periksa dengan logika bisnis dalam aplikasi apakah pengguna dapat mengakses objek tertentu. Apa yang Anda usulkan akan memberikan keamanan yang lebih baik, tetapi juga akan menimbulkan lebih banyak kerumitan. Pikirkan apakah itu sepadan.

Ini membuatnya sangat sulit ketika menangani pengaturan ulang kata sandi ...

Saat mengenkripsi data dengan sandi pengguna, data tersebut akan hilang saat pengguna lupa sandi. Dalam beberapa kasus, ini dapat diterima dan pengguna hanya perlu membuat akun baru. Jika tidak, terkadang hal ini diselesaikan dengan memberikan kunci dekripsi kepada pengguna saat menyiapkan akun mereka, yang dimaksudkan untuk dicetak dan disimpan. Ini adalah kunci "pintu belakang" yang dapat mendekripsi akun ketika kata sandi dilupakan.

Max Oct 01 2020 at 03:49

Anda ingin melindungi data. Tapi dari apa? Dari siapa?
Anda perlu menentukan skenario yang mungkin, dan kemudian Anda dapat mencoba menemukan cara untuk melindungi dari bahaya tertentu, dari cara tertentu penyerang dapat mencoba mencuri data Anda.

Bagaimana dengan peretasan fisik ? Bisakah seseorang masuk dan mencuri server Anda? Bisakah seseorang membuat salinan data langsung? Bisakah seseorang mengakses backup? ( karena Anda memiliki salinan cadangan , di dalam, di luar situs, dan semua cadangan itu dilindungi kata sandi , bukan?)

Jika Anda ingin mengenkripsi data, Anda perlu menentukan pada level mana Anda ingin mengenkripsi data .
Pada RDBMS tertentu, Anda dapat mengenkripsi seluruh DB di disk , dan menyimpan kunci di server DB. Ini dapat melindungi Anda jika seseorang mencuri salinan file DB Anda. Tetapi tidak akan melindungi Anda jika seseorang mencuri kredensial DB.
Atau Anda dapat meneruskan kunci enkripsi dengan string koneksi, tetapi hal-hal seperti ini dapat sangat bervariasi antara RDBMS yang berbeda.

Anda dapat memodifikasi aplikasi / situs web Anda untuk mengenkripsi semua data di setiap baris / kolom DB .
Sekarang Anda memiliki banyak keamanan, dan banyak masalah :

  • Bagaimana Anda mengurutkan tabel data terenkripsi? kamu tidak.
  • Indeks kolom ? tak berguna.
  • Dapatkah Anda melakukan SELECT ... WHERE Encrypted_Name_Column seperti '% Fox%' ? tidak, kamu tidak bisa.
  • Bagaimana Anda mengenkripsi kolom Tanggal / Waktu ? Apakah Anda mengonversi tanggal menjadi string dan kemudian mengenkripsi string tersebut? Semoga berhasil dengan mendekripsi ketika penghematan siang hari dimulai ...
  • Bagaimana Anda mengelola IV ( vektor inisialisasi ) dari algoritma enkripsi? Jika Anda mengenkripsi data yang sama, dengan kunci yang sama, dan IV yang sama, maka Anda mendapatkan keluaran terenkripsi yang sama. Jadi penyerang mungkin tidak dapat mendekripsi data, tetapi dapat mendeteksi bahwa nilai tertentu adalah sama , karena nilai terenkripsi sama.

Anda dapat melakukan semua ini, tetapi apakah itu sangat berharga?

Bagaimana Anda mengelola kunci enkripsi?
Biasanya Anda tidak secara langsung menggunakan kata sandi untuk mengenkripsi data . Biasanya Anda membuat kunci aman acak untuk mengenkripsi data, dan kemudian menggunakan kata sandi untuk mendapatkan kunci untuk mengenkripsi kunci yang Anda gunakan untuk data tersebut.
Dengan cara ini Anda dapat mengubah kata sandi tanpa perlu mengenkripsi ulang semua data.
Sekarang, jika Anda kehilangan kata sandi, Anda memerlukan rencana cadangan ... seperti salinan kunci enkripsi data, dienkripsi dengan kata sandi utama, digunakan hanya untuk menyetel ulang kata sandi. (tapi sekarang, Anda memiliki kata sandi utama, yang dapat mendekripsi semua data semua pengguna ... di mana Anda menyimpannya? di server dengan celah udara?)

Apakah lebih baik membagi layanan, dan mencoba mengurangi permukaan serangan?
Mengapa aplikasi / situs Anda membutuhkan kredensial DB? Anda dapat membuat aplikasi / situs web yang tidak pernah mengakses DB secara langsung, tetapi hanya mengakses data melalui layanan web. Layanan web untuk mengakses data bisa jadi berada di server kedua yang tidak dapat diakses dari internet. Kredensial DB, yang digunakan oleh server kedua, dapat disimpan di server ketiga dan diakses oleh jaringan dengan akun tertentu ...
Anda dapat membangun keamanan lapis demi lapis.

Mungkin saya baru saja memulai, keamanan situs web / aplikasi / db adalah argumen yang cukup luas.