Spec-Zone.ru › MySQL 5.7

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

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

  • Атрибут DEFINER

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

  • Примеры

  • Сироты хранимых объектов

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

Атрибут DEFINER

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

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

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

  • В противном случае, единственная разрешенная учетная запись — ваша собственная, указанная либо явно, либо как 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 впоследствии будет создана для целей, не связанных с объектом. В этом случае учетная запись «присваивает» себе объект и, имея соответствующие привилегии, может выполнить его, даже если это не предполагалось.

Для получения информации об учетных записях, используемых в качестве владельцев хранимых объектов в установке 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 в определении объекта, когда это возможно, чтобы ограничить его доступ только пользователями с разрешениями, соответствующими операциям, выполняемым объектом.

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

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

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

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

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

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

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

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

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

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

Spec-Zone.ru

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