Najpierw odpowiem na twoje pytanie „poboczne”:
masz całkowitą rację ze swoimi zmartwieniami i obawami, a każdy, kto projektuje aplikację, powinien myśleć o tym samym. Wszystko inne jest niechlujne i nieostrożne.
Aby złagodzić szkody, które może spowodować udany atak typu SQL injection, zdecydowanie powinieneś stosować zasadę najmniejszych uprawnień.
Konfiguracja systemu, który odpowiada Twoim wymaganiom, powinna być dość prosta.
Użyję nazw obiektów z twojego przykładu, z tym wyjątkiem, że zamiast minusów użyję podkreśleń. Dobrą praktyką jest używanie tylko małych liter, podkreśleń i cyfr w nazwach obiektów, ponieważ ułatwi to życie.
/* create the database */
\c postgres postgres
CREATE DATABASE test_database WITH OWNER app_admin;
\c test_database postgres
/* drop public schema; other, less invasive option is to
REVOKE ALL ON SCHEMA public FROM PUBLIC */
DROP SCHEMA public;
/* create an application schema */
CREATE SCHEMA app AUTHORIZATION app_admin;
/* further operations won't need superuser access */
\c test_database app_admin
/* allow app_user to access, but not create objects in the schema */
GRANT USAGE ON SCHEMA app TO app_user;
/* PUBLIC should not be allowed to execute functions created by app_admin */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin
REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
/* assuming that app_user should be allowed to do anything
with data in all tables in that schema, allow access for all
objects that app_admin will create there */
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT SELECT, USAGE ON SEQUENCES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE app_admin IN SCHEMA app
GRANT EXECUTE ON FUNCTIONS TO app_user;
Jeśli jednak traktujesz zasadę najmniej poważnie, uprawnienia do tabeli powinieneś przyznawać indywidualnie i m.in. nie zezwalaj na app_user
do DELETE
i UPDATE
dane w tabelach, w których użytkownik nie musi tego robić.