PL/Perl now ties %ENV
PL/Perl is a great language, since it ties together two of my favourite pieces of technology: PostgreSQL and Perl. While I do usually refer to PL/Perl as the capability to run Perl code within PostgreSQL, the correct naming is eitherPL/Perl or PL/Perlu, where the former is the trusted language and the latter is the untrusted one.
A trusted language means that the code will run in a PostgreSQL sandbox, with lower permissions than a normal application.
This commit introduces a new protection level in the trusted languaged PL/Perl: is prevents the modification of the %ENV hash, that represents the enviromental settings for the running code.
An official CVE for the problem has been issued.
The trick to prevent modifications is really elegant, as often Perl is: using a tied hash to wrap up %ENV.
It works as follows:
- create a new class that implements the hash protector
tiethe%ENVto this new class- provide warnings when something tries to modify the
%ENVtied hash.
package PostgreSQL::InServer::WarnEnv;
use strict;
use warnings;
use Tie::Hash;
our @ISA = qw(Tie::StdHash);
sub STORE { warn "attempted alteration of \$ENV{$_[1]}"; }
sub DELETE { warn "attempted deletion of \$ENV{$_[1]}"; }
sub CLEAR { warn "attempted clearance of ENV hash"; }
The
PostgreSQL::InServer::WarnEnv class inherits from Tie::StdHash, a tie-able hash that already defines all the required methods and that requires you to only override those that are in your scope of interest.
In particular, WarnEnv overrides STORE, DELETE and CLEAR that are method used when adding, deleting of a value in the hash or clearing it all.
Then, it does suffice to tie the %ENV to this class, and in fact the PL/Perl implementation does:
tie %main::ENV, 'PostgreSQL::InServer::WarnEnv', %ENV or die $!;
that applies
WarnEnv as the class behind the behaviour of main::ENV keeping all values of %ENV (that has been changed to a normal hash).
From now on, trying to modify %ENV will result in a warning according to the method used.
This patch has been backported on older PostgreSQL versions until 12.