Пользователю PostgreSQL-DB должно быть разрешено вызывать только функции

В настоящее время я использую PostgreSQL для своего приложения. Поскольку я пытаюсь поместить каждый SQL, содержащий транзакцию (т. е. insert, update, delete) в функцию, я наткнулся на эту проблему:

возможно ли, что пользователю базы данных может быть разрешено вызывать только функции и Select-операторы, в то время как он не может вызывать SQL-операторы, содержащие транзакцию? Под "функциями вызова" я подразумеваю любую функцию. Независимо от того, содержит ли он транзакцию или нет.

Я уже пытался создать пользователя, который может вызывать только функции и Select-операторы. Но я всегда заканчиваю с ошибкой при вызове функций, которые содержат транзакции. Насколько я понимаю, dbuser нуждается в разрешениях на запись, если он вызывает функцию, которая использует инструкцию insert, update или delete.

Я что-то пропустила? Неужели такой сценарий невозможен? С точки зрения безопасности это было бы действительно здорово, потому что вы в значительной степени предотвращаете SQL-инъекцию в первую очередь.

1 ответов


нет никакой " привилегии на SELECT". Все, что вам нужно-это привилегия EXECUTE функции. Соответствующая функция может работать с SECURITY DEFINER наследовать все привилегии владельца. Чтобы ограничить возможную эскалацию привилегий до минимума априори, сделайте роль демона собственными соответствующими функциями только с необходимыми привилегиями-не суперпользователем!

рецепт

в качестве суперпользователя ...

создать роль не суперпользователя myuser.

CREATE ROLE myuser PASSWORD ...;

создать групповую роль mygroup и сделать myuser член в нем.

CREATE ROLE mygroup;
GRANT mygroup TO myuser;

вы можете добавить больше пользователей, как myuser позже.

Do не предоставлять никаких привилегий вообще to myuser.
Только даруй это mygroup:

  • GRANT CONNECT ON DATABASE mydb TO mygroup;
  • GRANT USAGE ON SCHEMA public TO mygroup;
  • GRANT EXECUTE ON FUNCTION foo() TO mygroup;

удалить все привилегии для public что myuser не надо было.

REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;

может быть и больше. я цитирую руководство:

PostgreSQL предоставляет привилегии по умолчанию для некоторых типов объектов PUBLIC. По умолчанию в таблицах PUBLIC привилегии не предоставляются, столбцов, схемы или таблицы. Для других типов значение по умолчанию привилегии, предоставляемые общественности, являются следующими:CONNECT и CREATE TEMP TABLE для баз данных; EXECUTE привилегия для функций; и USAGE привилегия для языки. Владелец объекта может, конечно, REVOKE как по умолчанию и предоставленные привилегии. (Для обеспечения максимальной безопасности, выпуск the REVOKE в той же транзакции, которая создает объект; то есть нет окна, в котором другой пользователь может использовать объект.) Кроме того, эти начальные настройки привилегий по умолчанию можно изменить с помощью .

создать демон роль to собственные соответствующие функции.

CREATE ROLE mydaemon;

предоставлять только привилегии, необходимые для выполнения этих функций mydaemon (включая EXECUTE ON FUNCTION Разрешить вызов другой функции). Опять же, вы можете использовать групповые роли для связывания привилегий и предоставления их mydaemon

GRANT bundle1 TO mydaemon;

кроме того, вы можете использовать DEFAULT PRIVILEGES для автоматического предоставления определенных привилегий для будущих объектов пакету или демону напрямую:

ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES    TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE  ON SEQUENCES TO bundle1;

это касается только роли исполнили это за. в документации:

если FOR ROLE опущено, предполагается текущая роль.

чтобы также охватить ранее существующие объекты в схеме (см. Роб):

GRANT SELECT ON ALL TABLES    IN SCHEMA public TO bundle1;
GRANT USAGE  ON ALL SEQUENCES IN SCHEMA public TO bundle1;

сделать mydaemon собственные соответствующие функции. Может выглядеть так:

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 ..

###Примечание
Из-за эта ошибка в текущей версии 1.16.1 из pgAdmin попробуйте команды

REVOKE EXECUTE ON FUNCTION foo() FROM public;

отсутствует в обратном сценарии DDL. Не забудьте добавить его, при воссоздании.
Эта ошибка исправлена в текущей версии pgAdmin 1.18.1.