Korisnici i dozvole u bazi podataka
Kako da napraviš zasebnog korisnika za svaku aplikaciju u MySQL-u i PostgreSQL-u, dodeliš minimalne dozvole i proveriš da ništa dodatno nije dozvoljeno.
Ažurirano 23. avgust 2026.
Aplikacija koja radi kao root ili postgres predaje svaku bazu na mašini napadaču pri prvoj ranjivosti. Namenski korisnik sa privilegijama samo na svojoj šemi ograničava štetu na jedan projekat.
MySQL i MariaDB
Korisnik je ovde par „ime i host", i to je glavni izvor zabune:
CREATE USER 'shop'@'localhost' IDENTIFIED BY 'long-random-password';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'shop'@'localhost';
FLUSH PRIVILEGES;
'shop'@'localhost' i 'shop'@'%' su dva različita korisnika sa različitim lozinkama. Ne pravi zapise sa hostom % osim ako je neophodno: on dozvoljava prijavu sa svake adrese.
Privilegije na strukturi su potrebne samo tokom migracija:
GRANT CREATE, ALTER, DROP, INDEX, REFERENCES ON shop.* TO 'shop_migrate'@'localhost';
Razdvajanje aplikativne role i role za migracije je dobra praksa: običan upit tada fizički ne može da obriše tabelu.
Proveri:
SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'shop'@'localhost';
Promena lozinke i brisanje:
ALTER USER 'shop'@'localhost' IDENTIFIED BY 'new-password';
DROP USER 'shop'@'localhost';
PostgreSQL
Rola i njene privilegije na bazi i šemi:
CREATE ROLE shop WITH LOGIN PASSWORD 'long-random-password';
CREATE DATABASE shop OWNER shop;
REVOKE ALL ON DATABASE shop FROM PUBLIC;
Za rolu samo za čitanje (izveštaji, analitika, panel za nadzor):
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;
Poslednja linija je obavezna: bez nje rola neće videti tabele napravljene nakon dodele privilegija, i za mesec dana izveštaji će pući na novim podacima.
Proveri:
\du
\l
\dp
Šta mora da bude zaključano
- Nijedna aplikativna rola nije superuser.
- Svaki projekat ima svoju bazu i svog korisnika.
- Lozinke su duge i nasumične, i različite za različite projekte.
- Spoljna prijava je dozvoljena samo za adrese kojima je potrebna — udaljeni pristup.
- MySQL nema anonimne korisnike i nema test bazu:
mariadb-secure-installationto radi.
Česte greške
| Simptom | Uzrok |
|---|---|
Access denied sa ispravnom lozinkom | Poklopilo se drugo pravilo za host, na primer ''@'localhost' |
Privilegije dodeljene, ali SELECT ne radi | PostgreSQL-u nedostaje USAGE ON SCHEMA |
| Nova tabela nije vidljiva roli | DEFAULT PRIVILEGES nisu postavljene |
| Aplikacija je obrisala sve tokom neuspele migracije | Aplikativna rola je imala DROP privilegije |
| Lozinka je vidljiva u istoriji komandi | Postavljaj lozinke iz fajla, očisti ~/.mysql_history |
Čuvaj lozinke baze u fajlu okruženja servisa sa dozvolama
600, ne u kodu. Ako dođe do kompromitacije, menjaš jednu liniju i restartuješ, a ne ponovo gradiš ceo projekat.