Skip to content

Commit

Permalink
Revert "Provide inclusive names allowlist and denylist"
Browse files Browse the repository at this point in the history
This reverts commit 0b66d70.
  • Loading branch information
khwilliamson committed Mar 24, 2022
1 parent 7ddf4b5 commit 19873f3
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 307 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Expand Up @@ -952,7 +952,7 @@ Michiel Beijen <mb@x14.nl>
Mik Firestone <fireston@lexmark.com>
Mike Doherty <mike@mikedoherty.ca>
Mike Fletcher <fletch@phydeaux.org>
Mike Fulton <mikefultonpersonal@gmail.com>
Mike Fulton <61100689+mikefultondev@users.noreply.github.com>
Mike Giroux <rmgiroux@acm.org>
Mike Guy <mjtg@cam.ac.uk>
Mike Heins <mike@bill.iac.net>
Expand Down
2 changes: 0 additions & 2 deletions MANIFEST
Expand Up @@ -3852,8 +3852,6 @@ dist/Locale-Maketext/t/90_utf8.t See if Locale::Maketext works
dist/Locale-Maketext/t/91_backslash.t See if Locale::Maketext works
dist/Locale-Maketext/t/92_blacklist.t See if Locale::Maketext works
dist/Locale-Maketext/t/93_whitelist.t See if Locale::Maketext works
dist/Locale-Maketext/t/94_denylist.t See if Locale::Maketext works
dist/Locale-Maketext/t/95_allowlist.t See if Locale::Maketext works
dist/Module-CoreList/Changes Module::CoreList Changes
dist/Module-CoreList/corelist The corelist command-line utility
dist/Module-CoreList/identify-dependencies A usage example for Module::CoreList
Expand Down
5 changes: 0 additions & 5 deletions dist/Locale-Maketext/ChangeLog
@@ -1,10 +1,5 @@
Revision history for Perl suite Locale::Maketext

2022-01-14
* Release 1.30 to CPAN
* Provide alternate methods allowlist and denylist for
whitelist and blacklist, respectively

2020-01-19
* Release 1.29 to CPAN
* Replace multiple 'use vars' by 'our'
Expand Down
49 changes: 10 additions & 39 deletions dist/Locale-Maketext/lib/Locale/Maketext.pm
Expand Up @@ -25,7 +25,7 @@ BEGIN {
}


our $VERSION = '1.30';
our $VERSION = '1.29';
our @ISA = ();

our $MATCH_SUPERS = 1;
Expand Down Expand Up @@ -136,20 +136,19 @@ sub fail_with { # an actual attribute method!

#--------------------------------------------------------------------------

sub _exclude {
my ( $handle, @methods ) = @_;
sub blacklist {
my ( $handle, @methods ) = @_;

unless ( defined $handle->{'denylist'} ) {
unless ( defined $handle->{'blacklist'} ) {
no strict 'refs';

# Don't let people call methods they're not supposed to from maketext.
# Explicitly exclude all methods in this package that start with an
# underscore on principle.
$handle->{'denylist'} = {
$handle->{'blacklist'} = {
map { $_ => 1 } (
qw/
blacklist
denylist
encoding
fail_with
failure_handler_auto
Expand All @@ -161,55 +160,30 @@ sub _exclude {
maketext
new
whitelist
allowlist
/, grep { /^_/ } keys %{ __PACKAGE__ . "::" }
),
};
}

if ( scalar @methods ) {
$handle->{'denylist'} = { %{ $handle->{'denylist'} }, map { $_ => 1 } @methods };
$handle->{'blacklist'} = { %{ $handle->{'blacklist'} }, map { $_ => 1 } @methods };
}

delete $handle->{'_external_lex_cache'};
return;
}

sub blacklist {
my ( $handle, @methods ) = @_;
_exclude ( $handle, @methods );
return;
}

sub denylist {
my ( $handle, @methods ) = @_;
_exclude ( $handle, @methods );
return;
}

sub _include {
sub whitelist {
my ( $handle, @methods ) = @_;
if ( scalar @methods ) {
$handle->{'allowlist'} = {} unless defined $handle->{'allowlist'};
$handle->{'allowlist'} = { %{ $handle->{'allowlist'} }, map { $_ => 1 } @methods };
$handle->{'whitelist'} = {} unless defined $handle->{'whitelist'};
$handle->{'whitelist'} = { %{ $handle->{'whitelist'} }, map { $_ => 1 } @methods };
}

delete $handle->{'_external_lex_cache'};
return;
}

sub whitelist {
my ( $handle, @methods ) = @_;
_include ( $handle, @methods );
return;
}

sub allowlist {
my ( $handle, @methods ) = @_;
_include ( $handle, @methods );
return;
}

#--------------------------------------------------------------------------

sub failure_handler_auto {
Expand Down Expand Up @@ -254,7 +228,6 @@ sub new {
my $class = ref($_[0]) || $_[0];
my $handle = bless {}, $class;
$handle->blacklist;
$handle->denylist;
$handle->init;
return $handle;
}
Expand Down Expand Up @@ -706,10 +679,8 @@ sub _compile {
}
elsif($m =~ /^\w+$/s
&& !$handle->{'blacklist'}{$m}
&& !$handle->{'denylist'}{$m}
&& ( !defined $handle->{'whitelist'} || $handle->{'whitelist'}{$m} )
&& ( !defined $handle->{'allowlist'} || $handle->{'allowlist'}{$m} )
# exclude anything fancy and restrict to the allowlist/denylist (and historical whitelist/blacklist).
# exclude anything fancy and restrict to the whitelist/blacklist.
) {
push @code, ' $_[0]->' . $m . '(';
}
Expand Down
54 changes: 21 additions & 33 deletions dist/Locale-Maketext/lib/Locale/Maketext.pod
Expand Up @@ -307,9 +307,9 @@ interested in hearing about it.)
These two methods are discussed in the section "Controlling
Lookup Failure".

=item $lh->denylist(@list) <or> $lh->blacklist(@list)
=item $lh->blacklist(@list)

=item $lh->allowlist(@list) <or> $lh->whitelist(@list)
=item $lh->whitelist(@list)

These methods are discussed in the section "Bracket Notation
Security".
Expand Down Expand Up @@ -875,17 +875,17 @@ bracket notation methods from normal class or object methods. This
design makes it vulnerable to format string attacks whenever it is
used to process strings provided by untrusted users.

Locale::Maketext does support denylist and allowlist functionality
Locale::Maketext does support blacklist and whitelist functionality
to limit which methods may be called as bracket notation methods.

By default, Locale::Maketext denies all methods in the
By default, Locale::Maketext blacklists all methods in the
Locale::Maketext namespace that begin with the '_' character,
and all methods which include Perl's namespace separator characters.

The default denylist for Locale::Maketext also prevents use of the
The default blacklist for Locale::Maketext also prevents use of the
following methods in bracket notation:

denylist
blacklist
encoding
fail_with
failure_handler_auto
Expand All @@ -896,56 +896,44 @@ following methods in bracket notation:
language_tag
maketext
new
allowlist
whitelist
blacklist

This list can be extended by either deny-listing additional "known bad"
methods, or allow-listing only "known good" methods.
This list can be extended by either blacklisting additional "known bad"
methods, or whitelisting only "known good" methods.

To prevent specific methods from being called in bracket notation, use
the denylist() method:
the blacklist() method:

my $lh = MyProgram::L10N->get_handle();
$lh->denylist(qw{my_internal_method my_other_method});
$lh->blacklist(qw{my_internal_method my_other_method});
$lh->maketext('[my_internal_method]'); # dies

To limit the allowed bracked notation methods to a specific list, use the
allowlist() method:
whitelist() method:

my $lh = MyProgram::L10N->get_handle();
$lh->allowlist('numerate', 'numf');
$lh->whitelist('numerate', 'numf');
$lh->maketext('[_1] [numerate, _1,shoe,shoes]', 12); # works
$lh->maketext('[my_internal_method]'); # dies

The denylist() and allowlist() methods extend their internal lists
whenever they are called. To reset the denylist or allowlist, create
The blacklist() and whitelist() methods extend their internal lists
whenever they are called. To reset the blacklist or whitelist, create
a new maketext object.

my $lh = MyProgram::L10N->get_handle();
$lh->denylist('numerate');
$lh->denylist('numf');
$lh->blacklist('numerate');
$lh->blacklist('numf');
$lh->maketext('[_1] [numerate,_1,shoe,shoes]', 12); # dies

For lexicons that use an internal cache, translations which have already
been cached in their compiled form are not affected by subsequent changes
to the allowlist or denylist settings. Lexicons that use an external
cache will have their cache cleared whenever the allowlist or denylist
settings change. The difference between the two types of caching is explained
to the whitelist or blacklist settings. Lexicons that use an external
cache will have their cache cleared whenever the whitelist of blacklist
setings change. The difference between the two types of caching is explained
in the "Readonly Lexicons" section.

Methods disallowed by the denylist cannot be permitted by the
allowlist.

NOTE: denylist() is the preferred method name to use instead of the
historical and non-inclusive method blacklist(). blacklist() may be
removed in a future release of this package and so it's use should be
removed from usage.

NOTE: allowlist() is the preferred method name to use instead of the
historical and non-inclusive method whitelist(). whitelist() may be
removed in a future release of this package and so it's use should be
removed from usage.
Methods disallowed by the blacklist cannot be permitted by the
whitelist.

=head1 AUTO LEXICONS

Expand Down
34 changes: 17 additions & 17 deletions dist/Locale-Maketext/t/92_blacklist.t
Expand Up @@ -48,46 +48,46 @@ my $res;
# get_handle blocked by default
$res = eval { $lh->maketext('[get_handle,en]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'get_handle blocked in bracket notation by default denylist' );
like( $@, qr/Can't use .* as a method name/, 'get_handle blocked in bracket notation by default blacklist' );

# _ambient_langprefs blocked by default
$res = eval { $lh->maketext('[_ambient_langprefs]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, '_ambient_langprefs blocked in bracket notation by default denylist' );
like( $@, qr/Can't use .* as a method name/, '_ambient_langprefs blocked in bracket notation by default blacklist' );

# _internal_method not blocked by default
$res = eval { $lh->maketext('[_internal_method]') };
is( $res, "_internal_method_response", '_internal_method allowed in bracket notation by default denylist' );
is( $@, '', 'no exception thrown by use of _internal_method under default denylist' );
is( $res, "_internal_method_response", '_internal_method allowed in bracket notation by default blacklist' );
is( $@, '', 'no exception thrown by use of _internal_method under default blacklist' );

# sprintf not blocked by default
$res = eval { $lh->maketext('[sprintf,%s,hello]') };
is( $res, "hello", 'sprintf allowed in bracket notation by default denylist' );
is( $@, '', 'no exception thrown by use of sprintf under default denylist' );
is( $res, "hello", 'sprintf allowed in bracket notation by default blacklist' );
is( $@, '', 'no exception thrown by use of sprintf under default blacklist' );

# denylisting sprintf and numerate
# blacklisting sprintf and numerate
$lh->blacklist( 'sprintf', 'numerate' );

# sprintf blocked by custom denylist
# sprintf blocked by custom blacklist
$res = eval { $lh->maketext('[sprintf,%s,hello]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom denylist' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom blacklist' );

# denylisting numf and _internal_method
# blacklisting numf and _internal_method
$lh->blacklist('numf');
$lh->blacklist('_internal_method');

# sprintf blocked by custom denylist
# sprintf blocked by custom blacklist
$res = eval { $lh->maketext('[sprintf,%s,hello]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom denylist after extension of denylist' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom blacklist after extension of blacklist' );

# _internal_method blocked by custom denylist
# _internal_method blocked by custom blacklist
$res = eval { $lh->maketext('[_internal_method]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom denylist after extension of denylist' );
like( $@, qr/Can't use .* as a method name/, 'sprintf blocked in bracket notation by custom blacklist after extension of blacklist' );

# custom_handler not in default or custom denylist
# custom_handler not in default or custom blacklist
$res = eval { $lh->maketext('[custom_handler]') };
is( $res, "custom_handler_response", 'custom_handler allowed in bracket notation by default and custom denylist' );
is( $@, '', 'no exception thrown by use of custom_handler under default and custom denylist' );
is( $res, "custom_handler_response", 'custom_handler allowed in bracket notation by default and custom blacklists' );
is( $@, '', 'no exception thrown by use of custom_handler under default and custom blacklists' );
42 changes: 21 additions & 21 deletions dist/Locale-Maketext/t/93_whitelist.t
Expand Up @@ -47,50 +47,50 @@ my $res;

# _internal_method not blocked by default
$res = eval { $lh->maketext('[_internal_method]') };
is( $res, "_internal_method_response", '_internal_method allowed when no allowlist defined' );
is( $@, '', 'no exception thrown by use of _internal_method without allowlist setting' );
is( $res, "_internal_method_response", '_internal_method allowed when no whitelist defined' );
is( $@, '', 'no exception thrown by use of _internal_method without whitelist setting' );

# allowlisting sprintf
# whitelisting sprintf
$lh->whitelist('sprintf');

# _internal_method blocked by allowlist
# _internal_method blocked by whitelist
$res = eval { $lh->maketext('[_internal_method]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, '_internal_method blocked in bracket notation by allowlist' );
like( $@, qr/Can't use .* as a method name/, '_internal_method blocked in bracket notation by whitelist' );

# sprintf allowed by allowlist
# sprintf allowed by whitelist
$res = eval { $lh->maketext('[sprintf,%s,hello]') };
is( $res, "hello", 'sprintf allowed in bracket notation by allowlist' );
is( $@, '', 'no exception thrown by use of sprintf with allowlist' );
is( $res, "hello", 'sprintf allowed in bracket notation by whitelist' );
is( $@, '', 'no exception thrown by use of sprintf with whitelist' );

# custom_handler blocked by allowlist
# custom_handler blocked by whitelist
$res = eval { $lh->maketext('[custom_handler]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'custom_handler blocked in bracket notation by allowlist' );
like( $@, qr/Can't use .* as a method name/, 'custom_handler blocked in bracket notation by whitelist' );

# adding custom_handler to allowlist
# adding custom_handler to whitelist
$lh->whitelist('custom_handler');

# sprintf still allowed by allowlist
# sprintf still allowed by whitelist
$res = eval { $lh->maketext('[sprintf,%s,hello]') };
is( $res, "hello", 'sprintf allowed in bracket notation by allowlist' );
is( $@, '', 'no exception thrown by use of sprintf with allowlist' );
is( $res, "hello", 'sprintf allowed in bracket notation by whitelist' );
is( $@, '', 'no exception thrown by use of sprintf with whitelist' );

# custom_handler allowed by allowlist
# custom_handler allowed by whitelist
$res = eval { $lh->maketext('[custom_handler]') };
is( $res, "custom_handler_response", 'custom_handler allowed in bracket notation by allowlist' );
is( $@, '', 'no exception thrown by use of custom_handler with allowlist' );
is( $res, "custom_handler_response", 'custom_handler allowed in bracket notation by whitelist' );
is( $@, '', 'no exception thrown by use of custom_handler with whitelist' );

# _internal_method blocked by allowlist
# _internal_method blocked by whitelist
$res = eval { $lh->maketext('[_internal_method]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, '_internal_method blocked in bracket notation by allowlist' );
like( $@, qr/Can't use .* as a method name/, '_internal_method blocked in bracket notation by whitelist' );

# adding fail_with to allowlist
# adding fail_with to whitelist
$lh->whitelist('fail_with');

# fail_with still blocked by blacklist
$res = eval { $lh->maketext('[fail_with,xyzzy]') };
is( $res, undef, 'no return value from blocked expansion' );
like( $@, qr/Can't use .* as a method name/, 'fail_with blocked in bracket notation by blacklist even when allowlisted' );
like( $@, qr/Can't use .* as a method name/, 'fail_with blocked in bracket notation by blacklist even when whitelisted' );

0 comments on commit 19873f3

Please sign in to comment.