Spec-Zone.ru › MySQL 9.2

27.7 Управление доступом к хранимым объектам

Хранимые программы (процедуры, функции, триггеры и события) и представления определяются до использования и, при обращении к ним, выполняется в контексте безопасности, который определяет их привилегии. Привилегии, применимые к выполнению хранимого объекта, контролируются его DEFINER атрибутом и SQL SECURITY характеристикой.

  • Атрибут DEFINER

  • Характеристика SQL SECURITY

  • Примеры

  • Объекты-сироты

  • Рекомендации по минимизации рисков

Атрибут DEFINER

Определение хранимого объекта может включать атрибут DEFINER, который назначает учётную запись MySQL. Если определение опускает атрибут DEFINER, то по умолчанию определяющим объектом является пользователь, который его создал.

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

  • Если у вас есть привилегия SET_ANY_DEFINER, вы можете указать любую учётную запись в качестве атрибута DEFINER. Если учётной записи не существует, генерируется предупреждение. Кроме того, для установки атрибута хранимого объекта DEFINER на учётную запись, имеющую привилегию SYSTEM_USER, вам необходимо иметь привилегию SYSTEM_USER.

  • В противном случае разрешена только ваша собственная учётная запись, указанная либо непосредственно, либо как CURRENT_USER или CURRENT_USER(). Вы не можете установить определяющего пользователя на любую другую учётную запись.

Создание хранимого объекта с несуществующей учётной записью DEFINER создаёт объект-сироту, что может иметь негативные последствия; см. Объекты-сироты.

Характеристика SQL SECURITY

Для хранимых процедур (и функций) и представлений в определении объекта может присутствовать характеристика SQL SECURITY со значением DEFINER или INVOKER, чтобы указать, выполняется ли объект в контексте определяющего пользователя или вызывающего пользователя. Если определение опускает характеристику SQL SECURITY, по умолчанию используется контекст определяющего пользователя.

Триггеры и события не имеют характеристики SQL SECURITY и всегда выполняются в контексте определяющего пользователя. Сервер вызывает эти объекты автоматически по мере необходимости, поэтому нет вызывающего пользователя.

Контексты безопасности определяющего и вызывающего пользователя различаются следующим образом:

  • Хранимый объект, выполняющийся в контексте безопасности определяющего пользователя, выполняется с привилегиями учётной записи, указанной в его атрибуте DEFINER. Эти привилегии могут полностью отличаться от привилегий вызывающего пользователя. Вызывающий пользователь должен иметь соответствующие привилегии для обращения к объекту (например, EXECUTE для вызова хранимой процедуры или SELECT для выбора из представления), но во время выполнения объекта привилегии вызывающего пользователя игнорируются, и учитываются только привилегии учётной записи DEFINER. Если у учётной записи DEFINER мало привилегий, объект соответственно ограничен в операциях, которые он может выполнять. Если учётная запись DEFINER обладает высокими привилегиями (например, административная учётная запись), объект может выполнять мощные операции независимо от того, кто его вызывает.

  • Хранимая процедура или представление, выполняющиеся в контексте безопасности вызывающего пользователя, могут выполнять только операции, для которых вызывающий пользователь имеет привилегии. Атрибут DEFINER не оказывает никакого влияния на выполнение объекта.

Примеры

Рассмотрим следующую хранимую процедуру, которая объявлена с SQL SECURITY DEFINER для выполнения в контексте безопасности определяющего пользователя:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE p1()
SQL SECURITY DEFINER
BEGIN
  UPDATE t1 SET counter = counter + 1;
END;

Любой пользователь, имеющий привилегию EXECUTE для p1, может вызвать её с помощью оператора CALL. Однако, когда p1 выполняется, она делает это в контексте безопасности определяющего пользователя, а следовательно, выполняется с привилегиями учётной записи 'admin'@'localhost', указанной в качестве её атрибута DEFINER. Эта учётная запись должна иметь привилегию EXECUTE для p1, а также привилегию UPDATE для таблицы t1, указанной в теле объекта. В противном случае процедура завершится ошибкой.

Теперь рассмотрим эту хранимую процедуру, которая идентична p1, за исключением того, что её характеристика SQL SECURITY имеет значение INVOKER:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE p2()
SQL SECURITY INVOKER
BEGIN
  UPDATE t1 SET counter = counter + 1;
END;

В отличие от p1, p2 выполняется в контексте безопасности вызывающего пользователя и, следовательно, с привилегиями вызывающего пользователя независимо от значения атрибута DEFINER. p2 завершится ошибкой, если вызывающий пользователь не обладает привилегией EXECUTE для p2 или привилегией UPDATE для таблицы t1.

Объекты хранимых данных без владельца

Объект хранимых данных без владельца — это объект, для которого атрибут DEFINER указывает на несуществующую учётную запись:

  • Объект хранимых данных без владельца может быть создан путём указания несуществующей учётной записи DEFINER во время создания объекта.

  • Существующий объект хранимых данных может стать объектом без владельца в результате выполнения инструкции DROP USER, которая удаляет учётную запись DEFINER объекта, или инструкции RENAME USER, которая переименовывает учётную запись DEFINER объекта.

Объект хранимых данных без владельца может представлять проблемы следующим образом:

  • Так как учётная запись DEFINER не существует, объект может работать некорректно, если он выполняется в контексте безопасности определяющего пользователя:

    • Для хранимой процедуры возникает ошибка при выполнении процедуры, если значение SQL SECURITY равно DEFINER, но учётная запись определяющего пользователя не существует.

    • Для триггера не рекомендуется, чтобы активация триггера происходила до фактического существования учётной записи. В противном случае поведение с проверкой привилегий не определено.

    • Для события возникает ошибка при выполнении события, если учётная запись не существует.

    • Для представления возникает ошибка при обращении к представлению, если значение SQL SECURITY равно DEFINER, но учётная запись определяющего пользователя не существует.

  • Объект может представлять угрозу безопасности, если несуществующая учётная запись DEFINER впоследствии будет снова создана для цели, не связанной с объектом. В этом случае учётная запись “присваивает” себе объект и, имея соответствующие привилегии, может его выполнить, даже если это не предполагалось.

Сервер применяет следующие проверки безопасности управления учётными записями, разработанные для предотвращения операций, которые (возможно, по ошибке) приводят к тому, что объекты хранимых данных становятся объектами без владельца, или которые приводят к принятию объектами хранимых данных, которые в настоящее время являются объектами без владельца:

  • Инструкция DROP USER завершается ошибкой, если любая учётная запись, подлежащая удалению, указана как атрибут DEFINER любого объекта хранимых данных. (То есть, инструкция завершается ошибкой, если удаление учётной записи приведет к тому, что объект хранимых данных станет объектом без владельца.)

  • Инструкция RENAME USER завершается ошибкой, если любая учётная запись, подлежащая переименованию, указана как атрибут DEFINER любого объекта хранимых данных. (То есть, инструкция завершается ошибкой, если переименование учётной записи приведёт к тому, что объект хранимых данных станет объектом без владельца.)

  • Инструкция CREATE USER завершается ошибкой, если любая учётная запись, подлежащая созданию, указана как атрибут DEFINER любого объекта хранимых данных. (То есть, инструкция завершается ошибкой, если создание учётной записи приведёт к тому, что учётная запись присвоит себе объект хранимых данных, который в настоящее время является объектом без владельца.)

В определённых ситуациях может потребоваться выполнить эти инструкции управления учётными записями, даже если они иначе завершатся ошибкой. Для этого, если пользователь имеет привилегию ALLOW_NONEXISTENT_DEFINER, эта привилегия переопределяет проверки безопасности для объектов без владельца, и инструкции завершатся с предупреждением, а не с ошибкой.

Чтобы получить информацию об учётных записях, используемых в качестве определяющих пользователей для объектов хранимых данных в установке MySQL, выполните запрос к таблице INFORMATION_SCHEMA.

Этот запрос определяет, какие таблицы INFORMATION_SCHEMA описывают объекты, у которых есть атрибут DEFINER:

mysql> SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS
       WHERE COLUMN_NAME = 'DEFINER';
+--------------------+------------+
| TABLE_SCHEMA       | TABLE_NAME |
+--------------------+------------+
| information_schema | EVENTS     |
| information_schema | ROUTINES   |
| information_schema | TRIGGERS   |
| information_schema | VIEWS      |
+--------------------+------------+

Результат показывает, какие таблицы нужно запросить, чтобы узнать, какие значения DEFINER объектов хранимых данных существуют и какие объекты имеют определённое значение DEFINER:

  • Чтобы определить, какие значения DEFINER существуют в каждой таблице, используйте следующие запросы:

    SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.EVENTS;
    SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.ROUTINES;
    SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.TRIGGERS;
    SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.VIEWS;
    

    Результаты запросов важны для любой учётной записи, отображаемой следующим образом:

    • Если учётная запись существует, удаление или переименование её приводит к тому, что объекты хранимых данных становятся объектами без владельца. Если вы планируете удалить или переименовать учётную запись, сначала рассмотрите возможность удаления связанных с ней объектов хранимых данных или их повторного определения с другим определяющим пользователем.

    • Если учётная запись не существует, её создание приводит к тому, что она присваивает себе в настоящее время объекты хранимых данных без владельца. Если вы планируете создать учётную запись, рассмотрите, должны ли к ней быть привязаны объекты хранимых данных без владельца. Если нет, переопределите их с другим определяющим пользователем.

    Для повторного определения объекта с другим определяющим пользователем можно использовать ALTER EVENT или ALTER VIEW для непосредственного изменения учётной записи DEFINER событий и представлений. Для хранимых процедур и функций, а также для триггеров нужно удалить объект и повторно создать его, чтобы назначить другую учётную запись DEFINER

  • Чтобы определить, какие объекты имеют заданную учётную запись DEFINER, используйте следующие запросы, заменив интересующую вас учётную запись на user_name@host_name:

    SELECT EVENT_SCHEMA, EVENT_NAME FROM INFORMATION_SCHEMA.EVENTS
    WHERE DEFINER = 'user_name@host_name';
    SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE DEFINER = 'user_name@host_name';
    SELECT TRIGGER_SCHEMA, TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS
    WHERE DEFINER = 'user_name@host_name';
    SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
    WHERE DEFINER = 'user_name@host_name';
    

    Для таблицы ROUTINES, запрос включает столбец ROUTINE_TYPE, чтобы строки вывода различали, является ли DEFINER хранимой процедурой или хранимой функцией.

    Если учётная запись, которую вы ищете, не существует, все объекты, отображаемые этими запросами, являются объектами без владельца.

Рекомендации по минимизации рисков

Для минимизации рисков при создании и использовании хранимых объектов следуйте этим рекомендациям:

  • Не создавайте хранимые объекты без владельца (орфанные объекты); то есть, объекты, для которых атрибут DEFINER указывает на несуществующую учётную запись. Не допускайте возникновения орфанных объектов путём удаления или переименования учётной записи, указанной в атрибуте DEFINER любого существующего объекта.

  • Для хранимой процедуры или представления используйте SQL SECURITY INVOKER в определении объекта, когда это возможно, чтобы обеспечить доступ только пользователям с разрешениями, соответствующими операциям, выполняемым объектом.

  • Если вы создаёте хранимые объекты с контекстом исполнителя, используя учётную запись с привилегией SET_ANY_DEFINER, укажите явный атрибут DEFINER, который назначает учётную запись, обладающую только необходимыми для объекта разрешениями. Указывайте учётную запись с очень высокими привилегиями (DEFINER) только в крайних случаях.

  • Администраторы могут предотвратить создание пользователями хранимых объектов, которые используют учётные записи с очень высокими привилегиями (DEFINER), не предоставляя им привилегию SET_ANY_DEFINER.

  • Объекты с контекстом исполнителя следует создавать, учитывая, что они могут получать доступ к данным, для которых у вызывающего пользователя нет разрешений. В некоторых случаях вы можете предотвратить ссылки на эти объекты, не предоставляя неавторизованным пользователям определённые привилегии:

    • К хранимой процедуре не может обратиться пользователь, у которого нет привилегии EXECUTE для неё.

    • К представлению не может обратиться пользователь, у которого нет соответствующих разрешений ( SELECT для выбора данных, INSERT для вставки данных и т. д.).

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

    • Триггер активируется при доступе к таблице, с которой он связан, даже при обычном доступе к таблице пользователями без специальных разрешений.

    • Событие выполняется сервером по расписанию.

    В обоих случаях, если учётная запись DEFINER имеет очень высокие привилегии, объект может выполнить чувствительные или опасные операции. Это остаётся верным, даже если разрешения, необходимые для создания объекта, отозваны у учётной записи пользователя, который его создал. Администраторы должны проявлять особую осторожность при предоставлении пользователям привилегий на создание объектов.

  • По умолчанию, при выполнении процедуры с характеристикой SQL SECURITY DEFINER, MySQL Server не устанавливает активные роли для учётной записи MySQL, указанной в предложении DEFINER, устанавливаются только роли по умолчанию. Исключением является случай, когда системная переменная activate_all_roles_on_login включена, в этом случае MySQL Server устанавливает все роли, предоставленные пользователю DEFINER, включая обязательные роли. Следовательно, любые привилегии, предоставленные через роли, по умолчанию не проверяются при выполнении оператора CREATE PROCEDURE или CREATE FUNCTION. Для хранимых программ, если необходимо выполнение с ролями, отличными от стандартных, тело программы может выполнить SET ROLE для активации требуемых ролей. Это следует делать с осторожностью, так как привилегии, назначенные ролям, могут быть изменены.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/stored-objects-security.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API