linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/lessons/pg-lab-44-1-security

lesson ── postgres-labs ── ~20 мин ── 3 шагов

search_path и SECURITY DEFINER: воспроизведи подмену

SECURITY DEFINER-функция исполняется с правами владельца. Если внутри неё есть неквалифицированное имя таблицы, а search_path не закреплён, чужой объект можно подсунуть через search_path - и функция выполнит подделку с правами владельца. Ты воспроизведёшь эту подмену и закроешь дыру. Автопроверка здесь подключается заново и видит search_path, заданный для роли, - именно так подмена и проявляется на практике. Сначала предсказывай, потом проверяй.

▶ интерактивный sandbox

Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.

запустить sandbox →

stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Создай SECURITY DEFINER-функцию без закреплённого search_path

    Заведи «настоящую» таблицу и функцию, читающую её по неквалифицированному имени:

    sql
    CREATE TABLE public.secret (v text);
    INSERT INTO public.secret VALUES ('real');
    CREATE FUNCTION read_secret() RETURNS text
    LANGUAGE sql SECURITY DEFINER
    AS $$ SELECT v FROM secret LIMIT 1 $$;

    Предскажи, что вернёт SELECT read_secret(); сейчас.

    ✓ Функция возвращает 'real' - читает public.secret. Пока всё честно.

  2. 02

    Подсунь чужой объект через search_path роли

    Создай свою схему с таблицей того же имени и поставь её первой в search_path роли:

    sql
    CREATE SCHEMA evil;
    CREATE TABLE evil.secret (v text);
    INSERT INTO evil.secret VALUES ('fake');
    ALTER ROLE student SET search_path = evil, public;

    search_path роли подхватывают новые подключения. Предскажи: что вернёт read_secret() в новом соединении - 'real' или 'fake'? Функция без закреплённого search_path возьмёт первое подходящее secret.

    подсказка

    ALTER ROLE влияет на новые сессии; автопроверка как раз открывает новое соединение.

    ✓ Функция вернула 'fake' - имя secret разрешилось в evil.secret. Это эскалация.

  3. 03

    Закрой дыру

    Пересоздай функцию защищённо: закрепи search_path и квалифицируй имя схемой.

    sql
    CREATE OR REPLACE FUNCTION read_secret() RETURNS text
    LANGUAGE sql SECURITY DEFINER
    SET search_path = pg_catalog, public
    AS $$ SELECT v FROM public.secret LIMIT 1 $$;

    search_path роли всё ещё evil, public, но функция его игнорирует. Предскажи: что вернёт read_secret() теперь? Когда закончишь, верни путь: ALTER ROLE student RESET search_path;.

    ✓ Снова 'real' при том же search_path роли - подмена больше не проходит.

Что ты узнал

SECURITY DEFINER исполняет функцию с правами владельца и наследует search_path вызывающего. Неквалифицированное имя внутри такой функции - канал подмены: чужой объект из первой схемы search_path подставится и выполнится с правами владельца. Защита: SET search_path на функции плюс квалификация имён схемой.

команды

  • CREATE FUNCTION f() ... SECURITY DEFINER SET search_path = pg_catalog, public ...закрепить search_path на функции
  • ALTER ROLE r SET search_path = a, b;search_path роли (подхватывается новыми сессиями)
  • SELECT * FROM pg_hba_file_rules WHERE auth_method='trust';найти опасные trust-правила

концепции

  • · SECURITY DEFINER исполняет функцию с правами владельца, не вызывающего
  • · незакреплённый search_path в такой функции - канал эскалации привилегий
  • · защита: SET search_path на функции + квалификация имён схемой

← предыдущая

Ловушки SQL: воспроизведи и перепиши

следующая →

Капстоун: расследование деградации прода

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки