Pengguna dan izin di database
Cara membuat pengguna terpisah untuk setiap aplikasi di MySQL dan PostgreSQL, memberikan izin minimal, dan memverifikasi bahwa tidak ada yang berlebihan.
Diperbarui 23 Agustus 2026
Aplikasi yang berjalan sebagai root atau postgres menyerahkan setiap basis data di mesin kepada penyerang pada kerentanan pertama. Pengguna khusus dengan hak istimewa hanya pada skema miliknya sendiri membatasi kerusakan pada satu proyek.
MySQL dan MariaDB
Pengguna di sini adalah pasangan "nama dan host", dan inilah sumber utama kebingungan:
CREATE USER 'shop'@'localhost' IDENTIFIED BY 'long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'shop'@'localhost';
FLUSH PRIVILEGES;
'shop'@'localhost' dan 'shop'@'%' adalah dua pengguna berbeda dengan kata sandi berbeda. Jangan membuat catatan dengan host % kecuali diperlukan: itu mengizinkan login dari alamat mana pun.
Hak istimewa pada struktur hanya diperlukan selama migrasi:
GRANT CREATE, ALTER, DROP, INDEX, REFERENCES ON shop.* TO 'shop_migrate'@'localhost';
Memisahkan peran aplikasi dan peran migrasi adalah praktik yang baik: kueri biasa kemudian secara fisik tidak dapat menghapus tabel.
Periksa:
SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'shop'@'localhost';
Mengubah kata sandi dan menghapus:
ALTER USER 'shop'@'localhost' IDENTIFIED BY 'new-password';
DROP USER 'shop'@'localhost';
PostgreSQL
Peran dan hak istimewanya pada basis data dan skema:
CREATE ROLE shop WITH LOGIN PASSWORD 'long-random-password';
CREATE DATABASE shop OWNER shop;
REVOKE ALL ON DATABASE shop FROM PUBLIC;
Untuk peran hanya-baca (laporan, analitik, panel pemantauan):
CREATE ROLE reader WITH LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE shop TO reader;
GRANT USAGE ON SCHEMA public TO reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO reader;
Baris terakhir wajib: tanpanya, peran tidak akan melihat tabel yang dibuat setelah hak istimewa diberikan, dan dalam sebulan laporan akan rusak pada data baru.
Periksa:
\du
\l
\dp
Yang harus dikunci
- Tidak ada peran aplikasi yang merupakan superuser.
- Setiap proyek memiliki basis data sendiri dan pengguna sendiri.
- Kata sandi panjang dan acak, serta berbeda untuk proyek yang berbeda.
- Login eksternal hanya diizinkan untuk alamat yang membutuhkannya — akses jarak jauh.
- MySQL tidak memiliki pengguna anonim dan tidak memiliki basis data uji:
mariadb-secure-installationmelakukan ini.
Kesalahan umum
| Gejala | Penyebab |
|---|---|
Access denied dengan kata sandi yang benar | Aturan host lain cocok, misalnya ''@'localhost' |
Hak istimewa diberikan, tetapi SELECT tidak berfungsi | PostgreSQL kekurangan USAGE ON SCHEMA |
| Tabel baru tidak terlihat oleh peran | DEFAULT PRIVILEGES tidak diatur |
| Aplikasi menghapus semuanya selama migrasi yang gagal | Peran aplikasi memiliki hak istimewa DROP |
| Kata sandi terlihat di riwayat perintah | Atur kata sandi dari file, bersihkan ~/.mysql_history |
Simpan kata sandi basis data di file lingkungan layanan dengan izin
600, bukan di dalam kode. Jika terjadi kompromi, Anda mengubah satu baris dan memulai ulang, bukan membangun ulang seluruh proyek.