Skip to content
VDS · Basis data

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-installation melakukan ini.

Kesalahan umum

GejalaPenyebab
Access denied dengan kata sandi yang benarAturan host lain cocok, misalnya ''@'localhost'
Hak istimewa diberikan, tetapi SELECT tidak berfungsiPostgreSQL kekurangan USAGE ON SCHEMA
Tabel baru tidak terlihat oleh peranDEFAULT PRIVILEGES tidak diatur
Aplikasi menghapus semuanya selama migrasi yang gagalPeran aplikasi memiliki hak istimewa DROP
Kata sandi terlihat di riwayat perintahAtur 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.