Перейти к основному содержимому

Доверенный и недоверенный PL/Perl

примечание

Эта страница переведена при помощи нейросети GigaChat.

Обычно PL/Perl устанавливается как «доверенный» язык программирования с именем plperl. В этой настройке некоторые операции Perl отключены для сохранения безопасности. В целом, те операции, которые ограничиваются, это те, которые взаимодействуют со средой. Это включает в себя операции с дескрипторами файлов, require, и use (для внешних модулей). Нет способа получить доступ к внутренним компонентам процесса сервера баз данных или получить доступ уровня ОС с разрешениями процесса сервера, как это может сделать функция на языке C. Таким образом, любому непривилегированному пользователю базы данных разрешается использовать этот язык.

Предупреждение

Trusted PL/Perl полагается на модуль Perl Opcode для сохранения безопасности. Perl документирует, что модуль не эффективен для использования в доверенном PL/Perl. Если потребности в безопасности несовместимы с неопределенностью в этом предупреждении, рассмотрите возможность выполнения REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC.

Пример функции, которая не будет работать, потому что операции с файловой системой запрещены по соображениям безопасности:

CREATE FUNCTION badfunc() RETURNS integer AS $$
my $tmpfile = "/tmp/badfile";
open my $fh, '>', $tmpfile
or elog(ERROR, qq{could not open the file "$tmpfile": $!});
print $fh "Testing writing to a file\n";
close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
return 1;
$$ LANGUAGE plperl;

Создание этой функции завершится неудачно, так как использование запрещенной операции будет обнаружено валидатором.

Иногда желательно писать Perl-функции, которые не ограничены. Например, может понадобиться Perl-функция для отправки почты. Чтобы справиться с этими случаями, PL/Perl также можно установить как «недоверенный» язык (обычно называемый PL/PerlU). В этом случае доступен полный язык Perl. При установке языка имя языка plperlu выберет ненадежную версию PL/Perl.

Автор функции PL/PerlU должен позаботиться о том, чтобы функция не могла быть использована для выполнения нежелательных действий, поскольку она сможет выполнять любые действия, которые мог бы выполнить пользователь, вошедший в систему в качестве администратора базы данных. Обратите внимание, что система баз данных разрешает только суперпользователям создавать функции на недоверенных языках.

Если вышеупомянутая функция была создана суперпользователем с использованием языка plperlu, выполнение будет успешным.

Анонимные блоки кода, написанные на Perl, могут использовать ограниченные операции, если язык указан как plperlu вместо plperl, но вызывающий объект должен быть суперпользователем.

Примечание

Хотя функции PL/Perl выполняются в отдельном интерпретаторе Perl для каждой роли SQL, все функции PL/PerlU, выполняемые в данном сеансе, выполняются в одном интерпретаторе Perl (который не является ни одним из тех, которые используются для функций PL/Perl). Это позволяет функциям PL/PerlU свободно обмениваться данными, но никакое общение между функциями PL/Perl и PL/PerlU невозможно.

Примечание

Perl не может поддерживать несколько интерпретаторов в одном процессе, если он был собран без соответствующих флагов, а именно либо usemultiplicity или useithreads. usemultiplicity предпочтительнее, если действительно нужно использовать потоки. Для получения более подробной информации см. man perlembed. Если PL/Perl используется с копией Perl, которая была собрана не таким образом, то возможно иметь только один интерпретатор Perl за сеанс, и поэтому любой один сеанс может выполнять либо функции PL/PerlU, либо функции PL/Perl, которые все вызываются одной и той же ролью SQL.