Застосунок не повинен ходити в базу під root. Якщо через SQL-ін'єкцію чи вкрадений .env хтось отримає доступ, права користувача визначають, скільки шкоди він зробить.
Користувач для застосунку:
CREATE USER 'app'@'10.0.0.%' IDENTIFIED BY 'довгий-випадковий-пароль';
GRANT SELECT, INSERT, UPDATE, DELETE ON app.* TO 'app'@'10.0.0.%';
Частина @'host' - невід'ємна частина облікового запису. 'app'@'10.0.0.%' - підключення лише з внутрішньої мережі; 'app'@'%' - звідусіль. 'app'@'localhost' і 'app'@'%' - два різні облікові записи з різними паролями й правами, що часто плутає.
Окремий користувач для міграцій:
CREATE USER 'migrator'@'10.0.0.%' IDENTIFIED BY '...';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, REFERENCES
ON app.* TO 'migrator'@'10.0.0.%';
Застосунок працює з обмеженими правами, а при деплої міграції запускаються з окремими обліковими даними. Тоді ін'єкція не зможе виконати DROP TABLE.
Інші облікові записи за призначенням:
backup-SELECT,SHOW VIEW,TRIGGER,LOCK TABLES,EVENT,PROCESS(для дампів);readonlyдля аналітики й BI - лишеSELECT, бажано на репліці;- моніторинг -
PROCESS,REPLICATION CLIENTіSELECTнаperformance_schema.
Чого не давати застосунку:
ALL PRIVILEGESчи права на*.*;SUPERта адміністративні динамічні привілеї;FILE- дає змогу читати й писати файли на сервері (LOAD DATA INFILE,SELECT ... INTO OUTFILE);GRANT OPTION.
Перевірити права:
SHOW GRANTS FOR 'app'@'10.0.0.%';
Що змінилося в MySQL 8:
GRANTбільше не створює користувача неявно - спершуCREATE USER;- зміна пароля -
ALTER USER 'app'@'10.0.0.%' IDENTIFIED BY '...'; - плагін автентифікації за замовчуванням -
caching_sha2_password; - для груп прав є ролі (
CREATE ROLE).
Пароль застосунку зберігається в .env (DB_USERNAME, DB_PASSWORD), а не в коді чи репозиторії, і змінюється, якщо .env міг потрапити в чужі руки.