Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / has_function_privilege - непонятная работа / 9 сообщений из 9, страница 1 из 1
09.02.2022, 12:24
    #40132781
pg000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
непонятная работа has_function_privilege

доступа к базе у юзера нет, а права на выполнение функции есть

Код: plsql
1.
2.
3.
4.
5.
SELECT has_database_privilege('myuser1', 'mydb1', 'CONNECT')
-- false

SELECT current_database(), has_function_privilege('myuser1', 16437, 'EXECUTE')
-- mydb1, true



Кто-нибудь может прокомментировать ?
...
Рейтинг: 0 / 0
09.02.2022, 13:15
    #40132800
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
pg000
непонятная работа has_function_privilege

доступа к базе у юзера нет, а права на выполнение функции есть

Код: plsql
1.
2.
3.
4.
5.
SELECT has_database_privilege('myuser1', 'mydb1', 'CONNECT')
-- false

SELECT current_database(), has_function_privilege('myuser1', 16437, 'EXECUTE')
-- mydb1, true



Кто-нибудь может прокомментировать ?


А почему нет? Это несвязанные уровни доступа.


Например в какой ситуации это может быть надо:
psql -U postgres -d mydb1
становимся пользователем myuser1
set role myuser1;
далее от myuser1 выполняем хранимку нужную при том что у myuser1 нет права на коннект.



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
09.02.2022, 14:06
    #40132813
pg000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
Хорошо,
не будем привязываться к connect

Создаём новую базу и убираем права роли PUBLIC (чтобы не мешались)
Код: plsql
1.
2.
3.
4.
5.
CREATE ROLE myuser1;

CREATE DATABASE mydb1;

REVOKE ALL ON DATABASE "mydb1" FROM PUBLIC;


Также убираем права на схему PUBLIC роли PUBLIC (чтобы не мешались)
И получаем разное поведение has_table_privilege и has_function_privilege

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
\c mydb1

SET SESSION AUTHORIZATION postgres;

REVOKE ALL ON SCHEMA public FROM PUBLIC;

CREATE TABLE mytbl1 ( field1 integer );

SELECT has_table_privilege('myuser1', 'mytbl1', 'SELECT');
-- false

CREATE OR REPLACE FUNCTION myfn1 ()
RETURNS integer AS
$$
BEGIN
    RETURN 1;
END
$$ LANGUAGE plpgsql;

SELECT myfn1();

SELECT oid, * FROM pg_proc WHERE proname='myfn1';

SELECT current_database(), has_function_privilege('myuser1', 130458, 'EXECUTE');
-- true


На просмотр данных из таблицы прав нет, а на выполнение функции есть.
...
Рейтинг: 0 / 0
09.02.2022, 15:03
    #40132830
pg000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
Опаньки,
всё по документации, но крайне неожиданно.

CREATE FUNCTION
Также следует помнить о том, что по умолчанию право выполнения для создаваемых функций имеет роль PUBLIC автоматом (за подробностями обратитесь к GRANT).

GRANT
PostgreSQL по умолчанию назначает группе PUBLIC определённые права для некоторых типов объектов. Для таблиц, столбцов, последовательностей, обёрток сторонних данных, сторонних серверов, больших объектов, схем или табличных пространств PUBLIC по умолчанию никаких прав не имеет. Для других типов объектов PUBLIC имеет следующие права по умолчанию:
CONNECT и TEMPORARY (создание временных таблиц) для баз данных;
EXECUTE — для функций,
USAGE — для языков и типов данных (включая домены).

Можно удивиться посмотрев в базах
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT fn_schema, fn_name, fn_oid, rolname, rolcanlogin::int, rolsuper::int, string_agg(privilege_type, ',' order by privilege_type) as "Granted", fn_args
FROM (SELECT nspname AS fn_schema, proname as fn_name, pg_proc.oid AS fn_oid, pg_get_function_arguments(pg_proc.oid) AS fn_args
	FROM pg_proc INNER JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid
	WHERE  nspname not like 'pg_%' and nspname <> 'information_schema'
) pr
CROSS JOIN pg_roles ro
CROSS JOIN (SELECT unnest('{EXECUTE}'::text[]) AS privilege_type) pt
WHERE has_function_privilege(rolname, fn_oid, privilege_type) = true
	and rolreplication = false and rolsuper = false --and rolcanlogin = true
	and rolname not like 'pg_%'
GROUP BY 1,2,8,3,4,5,6
ORDER BY 1,2,8,4
...
Рейтинг: 0 / 0
09.02.2022, 19:24
    #40132916
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
pg000,

Поскольку функция по умолчанию выполняется с правами того кто её запускает то никаких доступов к таблицам или ещё чему которых нет у запускающего функцию - не образуется.
Поэтому и public доступ есть к функции по умолчанию на выполнение.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
09.02.2022, 20:29
    #40132941
pg000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
Это по умолчанию.

Но есть же функции с SECURITY DEFINER

CREATE FUNCTION

Получается, чтобы понять может ли что-то поменять функция нужно смотреть исходный код.
При большом количестве функций это уже нужно писать код для такой проверки.
Ведь никаких намёков даже при pg_dump

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
pg_dump -U postgres -d mydb1 --schema-only | grep -vP '^\s*(#|;|$)' | grep -vP '^--'

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
CREATE FUNCTION public.myfn1() RETURNS integer
    LANGUAGE plpgsql
    AS $$
BEGIN
    RETURN 1;
END
$$;
ALTER FUNCTION public.myfn1() OWNER TO postgres;
SET default_tablespace = '';
SET default_table_access_method = heap;
CREATE TABLE public.mytbl1 (
    field1 integer
);
ALTER TABLE public.mytbl1 OWNER TO postgres;
REVOKE ALL ON SCHEMA public FROM PUBLIC;


Или нужно взять за привычку сразу же после создания функции выполнять.

Код: plsql
1.
REVOKE ALL ON FUNCTION ... FROM PUBLIC;
...
Рейтинг: 0 / 0
09.02.2022, 21:47
    #40132952
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
pg000,

Про security definer там вообще много gotchas есть включая подмену search_path например
и предполагается что тот кто их пишет внимательно прочитал и осознал всё что написано в
https://www.postgresql.org/docs/14/sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY
и в общем grant for publiс там не самая большая опасность.
Т.е. security definer функции должны проходить весьма отдельный и внимательный security audit.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
09.02.2022, 22:59
    #40132962
pg000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
Ну я вот не сторонник "административных" решений.

Мне вот понравилось когда-то...

Решений здесь два: радикальное и правильное. Радикальное - покарать нерадивого разработчика физически (сделайте ему массаж почек и печени), морально (устроить публичную психологическую порку), финансово (лишите премии). Но вы же понимаете, что все это плохо и поселит в глубине “чуткой” души разработчика обиду на вас. Может он был уставшим и просто недоглядел - бывает такое? Конечно бывает! Поэтому, решение правильное - автоматизируйте проверку кода
Возможно ещё на новых базах.
Код: plsql
1.
2.
3.
4.
ALTER DEFAULT PRIVILEGES IN SCHEMA public FOR ROLE postgres REVOKE ALL ON FUNCTIONS FROM PUBLIC;

CREATE SCHEMA myschema1
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema1 FOR ROLE postgres REVOKE ALL ON FUNCTIONS FROM PUBLIC;


Или на новых базах для будущих schema вообще вешать EVENT TRIGGER
Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE EVENT TRIGGER auto_grant_trigger
    ON ddl_command_end
    WHEN TAG IN (
            'CREATE SCHEMA',
            'ALTER SCHEMA'
        )
EXECUTE PROCEDURE auto_grant_func();
...
Рейтинг: 0 / 0
09.02.2022, 23:21
    #40132966
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
has_function_privilege - непонятная работа
pg000
Ну я вот не сторонник "административных" решений.

Мне вот понравилось когда-то...

Решений здесь два: радикальное и правильное. Радикальное - покарать нерадивого разработчика физически (сделайте ему массаж почек и печени), морально (устроить публичную психологическую порку), финансово (лишите премии). Но вы же понимаете, что все это плохо и поселит в глубине “чуткой” души разработчика обиду на вас. Может он был уставшим и просто недоглядел - бывает такое? Конечно бывает! Поэтому, решение правильное - автоматизируйте проверку кода

Возможно ещё на новых базах.
Код: plsql
1.
2.
3.
4.
ALTER DEFAULT PRIVILEGES IN SCHEMA public FOR ROLE postgres REVOKE ALL ON FUNCTIONS FROM PUBLIC;

CREATE SCHEMA myschema1
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema1 FOR ROLE postgres REVOKE ALL ON FUNCTIONS FROM PUBLIC;


Или на новых базах для будущих schema вообще вешать EVENT TRIGGER
Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE EVENT TRIGGER auto_grant_trigger
    ON ddl_command_end
    WHEN TAG IN (
            'CREATE SCHEMA',
            'ALTER SCHEMA'
        )
EXECUTE PROCEDURE auto_grant_func();



Тогда ещё проверку установки search_path для security definer хранимко надо делать.
Через проверку select proname, proconfig from pg_proc where prosecdef;

Идею автоматического убирания прав на public в принципе поддерживаю но гемороя с ручной раздачей прав оно добавит преизрядно.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / has_function_privilege - непонятная работа / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]