Mengamankan kata sandi DB

18

Melihat struktur sebagian besar situs web berbasis PHP / MySQL yang pernah saya lihat, tampaknya tidak terlalu sulit untuk membedakan kata sandi basis data jika Anda menggali sedikit, karena selalu ada pengaturan atau file konfigurasi di suatu tempat yang menyimpan informasi untuk login ke dalam DB. Selain tindakan pencegahan dasar untuk memastikan bahwa hak istimewa basis data saya dibatasi secara tepat untuk permintaan jarak jauh, opsi apa yang tersedia yang dapat saya terapkan dalam proyek saya sendiri untuk melindungi informasi ini?

Kaji
sumber
1
Untuk mengklarifikasi - Anda bertanya tentang menyimpan kredensial untuk masuk ke database dari situs web, dan bukan bagaimana cara menyimpan kata sandi dengan benar untuk pengguna situs web dalam database, benar?
Joe
Benar; itulah yang saya maksudkan.
Kaji

Jawaban:

10

Bukan jawaban langsung tentang penyimpanan kata sandi, tetapi saya biasanya menggunakan setidaknya dua koneksi basis data saat membuat webapps - yang digunakan 99% dari waktu untuk kegiatan yang terkait dengan pengguna, dengan hak istimewa terbatas, dan yang lain digunakan untuk fungsionalitas 'admin' (hapus pengguna, dll.).

Dalam beberapa kasus, ketika saya menginstal paket orang lain, saya akan menginstal dua contoh ... contoh publik yang hanya memiliki akses database untuk melakukan hal-hal umum tipe pengguna, dan contoh kedua yang dibatasi IP untuk subnet lokal saya (mungkin bahkan pada mesin yang berbeda) yang harus digunakan untuk aktivitas jenis 'admin'. Tidak ada yang memiliki akses untuk memodifikasi tabel, dll, meskipun ... Saya lebih suka masuk melalui alat database asli daripada membiarkan webapp untuk menjalankan tugas pembaruan sendiri yang belum diperiksa.

Anda dapat mengambilnya lebih jauh lagi, dan menambahkan lebih banyak koneksi khusus untuk tugas yang diberikan ... sehingga tugas-tugas pembuatan & manajemen kata sandi pengguna melalui pengguna yang memiliki hak istimewa tambahan pada tabel pengguna, login memiliki privasi database untuk diautentikasi dan tidak banyak lagi. , dll.

Dengan cara ini, jika ada serangan injeksi sql, pada sebagian besar halaman web itu tidak dapat benar-benar melakukan sesuatu yang signifikan - tidak dapat melihat hash kata sandi, tidak dapat menambahkan pengguna admin baru (bukan bahwa mereka akan dapat melakukan Bagaimanapun juga), dll. Tetap tidak akan membantu jika mereka berhasil mendapatkan shell pada mesin Anda, tetapi itu akan memperlambatnya.

Joe
sumber
1
Kami melakukan hal serupa. Namun, kami biasanya membuat akun baru untuk setiap pengguna / aplikasi basis data alih-alih melakukannya berdasarkan fungsionalitas. Ini memecahkan dua masalah bagi kita - 1) kita dapat membedakan penggunaan database dalam alat-alat seperti OEM (yaitu, kita dapat melihat siapa yang memalu database dengan granularity) dan 2) kita dapat secara individual menyesuaikan apa yang dilihat setiap pengguna dan memiliki akses ke dalam basis data.
ScottCher
7

Gunakan kata sandi satu kali , Kerberos , LDAP atau apa pun untuk menyimpan data akun Anda dan mengotentikasi / mengesahkan pengguna. Layanan direktori adalah cara yang baik untuk menyimpan informasi pengguna dan menggunakannya sebagai data akun backend.

Yasir Arsanukaev
sumber
4

Saya penggemar berat menggunakan otentikasi 'Ident' PostgreSQL di soket lokal kapan pun saya bisa. Dengan begitu, pengguna lokal dipetakan langsung ke pengguna Unix / Windows komputer lokal, dan saya tidak perlu khawatir menyimpan kata sandi sama sekali. Saya pikir ini belum merupakan opsi di MySQL.

Di mana database dan server web berada di dua mesin yang terpisah, saya menggunakan kata sandi MD5 melalui SSL: jika suatu permusuhan memiliki akses ke server frontend saya, itu hanya masalah waktu sebelum ia mengetahui bagaimana ia berkomunikasi dengan database.

Gaurav
sumber
3

Jika Anda menggunakan .NET Framework, Anda dapat melihat menggunakan string koneksi terenkripsi. Saya tidak tahu apakah hal seperti itu dimungkinkan dalam bahasa / kerangka kerja lain, tapi itu akan menjadi perlindungan lain untuk memastikan bahwa koneksi Anda tidak terganggu.

Di luar menggunakan string koneksi terenkripsi, menggunakan LDAP / Kerberos / Active Directory akan menjadi pilihan teraman Anda.

Jeremiah Peschka
sumber
3

Jika kata sandi Anda disimpan dalam teks biasa, gunakan hash (MD5, SHA), Luke!

Yasir Arsanukaev
sumber
OP tidak bertanya tentang menyimpan kata sandi pengguna. Tapi ya, tentu saja hash kata sandi pengguna Anda, tetapi jangan pernah menggunakan MD5 atau keluarga SHA untuk melakukannya! Gunakan bcrypt atau PBKDF2. Kalau tidak, Anda akan segera menemukan diri Anda dalam berita seperti perusahaan-perusahaan ini yang menggunakan MD5 dan SHA1 dan dengan demikian mengekspos penggunanya terhadap serangan brute force sederhana.
Nick Chammas
Tentu, pengasinan dan teknik lain diperlukan selain hanya hashing. Dan seseorang seharusnya tidak pernah mengimplementasikan primitif kripto sendiri (dirinya sendiri), melainkan menggunakan beberapa perpustakaan kripto yang telah teruji.
Yasir Arsanukaev
2

Bergantung pada bahasa pemrograman Anda, Anda bisa mengenkripsi kredensial login, tetapi jika Anda menjalankan bahasa yang ditafsirkan, maka tidak ada cara untuk memastikan bahwa seseorang tidak dapat mengetahui kredensial jika mereka mendapatkan akses ke sistem.

Jika Anda menjalankan C ++ atau sejenisnya, maka saya akan merekomendasikan Anda membuat / menemukan fungsi mengenkripsi / mendekripsi asin dan menjalankan kredensial melalui itu dan menyimpan hash yang dihasilkan sebagai file pada sistem.

Jika Anda menjalankan PHP atau sejenisnya, saya akan merekomendasikan Anda menulis pembungkus untuk mcrypt_encrypt()dan garam kredensial kemudian menjalankan beberapa kode kebingungan untuk memperlambat peretas jika mereka mendapatkan akses ke sistem.

Patrick
sumber
Jika Anda mengenkripsi kredensial, Anda perlu beberapa rahasia lain untuk mendekripsi lagi. Atau sebagai alternatif, bentuk terenkripsi menjadi rahasia, sehingga penyerang bisa menggunakannya. Beberapa detail hilang.
Peter Eisentraut