No hay "privilegio en SELECT
". Todo lo que necesita es el privilegio de EXECUTE
funciones La función relevante se puede ejecutar con SECURITY DEFINER
heredar todos los privilegios del propietario. Para restringir la posible escalada de privilegios a un mínimo a priori, haga que un rol de daemon posea funciones relevantes con solo los privilegios necesarios, ¡no un superusuario!
Receta
Como superusuario...
Cree un rol que no sea superusuario myuser
.
CREATE ROLE myuser PASSWORD ...;
Crear un rol de grupo mygroup
y hacer myuser
miembro en él.
CREATE ROLE mygroup;
GRANT mygroup TO myuser;
Es posible que desee agregar más usuarios como myuser
más tarde.
No conceder ningún privilegio a myuser
.
Solo concédelos a mygroup
:
GRANT CONNECT ON DATABASE mydb TO mygroup;
GRANT USAGE ON SCHEMA public TO mygroup;
GRANT EXECUTE ON FUNCTION foo() TO mygroup;
Quitar todo privilegios para public
que myuser
no debería haberlo hecho.
REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;
Puede haber más. Cito el manual:
Crear un rol de demonio poseer funciones relevantes.
CREATE ROLE mydaemon;
Otorgue solo los privilegios necesarios para ejecutar estas funciones a mydaemon
, (incluyendo EXECUTE ON FUNCTION
para permitir que se llame a otra función). Nuevamente, puede usar roles de grupo para agrupar privilegios y otorgarlos a mydaemon
GRANT bundle1 TO mydaemon;
Además, puede usar DEFAULT PRIVILEGES
para otorgar automáticamente ciertos privilegios para objetos futuros a un paquete o al daemon directamente:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE ON SEQUENCES TO bundle1;
Esto se aplica solo al rol para el que se ejecuta. Según la documentación:
Para cubrir también objetos preexistentes en el esquema (consulte comentario de Rob ):
GRANT SELECT ON ALL TABLES IN SCHEMA public TO bundle1;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bundle1;
Hacer mydaemon
propias funciones relevantes. Podría verse así:
CREATE OR REPLACE FUNCTION foo()
...
SECURITY DEFINER SET search_path = myschema, pg_temp;
ALTER FUNCTION foo() OWNER TO mydaemon;
REVOKE EXECUTE ON FUNCTION foo() FROM public;
GRANT EXECUTE ON FUNCTION foo() TO mydaemon;
GRANT EXECUTE ON FUNCTION foo() TO mygroup;
-- possibly others ..
###Nota
Debido a este error
en la versión actual 1.16.1 de pgAdmin
el comando necesario
REVOKE EXECUTE ON FUNCTION foo() FROM public;
falta en el script DDL de ingeniería inversa. Recuerde agregarlo cuando vuelva a crear.
Este error se solucionó en la versión actual pgAdmin 1.18.1.