Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке схеми й search_path у PostgreSQL і як вони впливають на безпеку?

Схема - простір імен усередині бази. Таблиці billing.invoices і public.invoices - різні об'єкти. За замовчуванням усе створюється в схемі public.

CREATE SCHEMA billing;
CREATE TABLE billing.invoices (...);

search_path - список схем, у яких PostgreSQL шукає об'єкт, названий без схеми:

SHOW search_path;           -- "$user", public
SET search_path = billing, public;
SELECT * FROM invoices;     -- billing.invoices

"$user" - схема з ім'ям поточного користувача, якщо вона існує.

Навіщо схеми:

  • модулі застосунку: billing, analytics, audit - окремі права й зрозуміла структура;
  • мультитенантність «схема на тенанта»: однакові таблиці в tenant_42, tenant_43, перемикання через search_path. Ізоляція краща за колонку tenant_id, але тисячі схем ускладнюють міграції й навантажують каталог;
  • розширення окремо від даних (CREATE EXTENSION pg_trgm SCHEMA extensions);
  • права: GRANT USAGE ON SCHEMA analytics TO bi_reader - доступ до всієї групи таблиць.

Безпека - головне про search_path:

1. Підміна об'єктів. Якщо користувач може створювати об'єкти в схемі, що стоїть у search_path раніше за потрібну, він може «перехопити» ім'я таблиці чи функції. Саме тому з PostgreSQL 15 звичайні користувачі не можуть створювати об'єкти в public за замовчуванням (раніше могли всі).

2. Функції з SECURITY DEFINER виконуються з правами власника. Якщо в них не зафіксовано search_path, зловмисник створює функцію з тим самим ім'ям у своїй схемі - і вона виконується з правами власника:

CREATE FUNCTION billing.close_period() RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = billing, pg_temp
AS $$ ... $$;

pg_temp останнім - щоб тимчасові об'єкти сесії не могли нічого підмінити.

У Laravel:

  • 'search_path' => 'public' у конфігурації з'єднання pgsql (ключ search_path);
  • міграції й моделі можуть звертатися до схеми явно: protected $table = 'billing.invoices';
  • PgBouncer у режимі transaction pooling: SET search_path на рівні сесії «протікає» між клієнтами, що ділять з'єднання. Безпечніше задавати search_path для ролі (ALTER ROLE app SET search_path = ...) чи використовувати повні імена.

Правило: у продакшен-базі користувач застосунку не повинен мати права CREATE у схемах, які є в search_path інших ролей.

Докладніше в документації: Схеми: шлях пошуку

Схожі питання