[Melbourne-pm] security hole

Paul Fenwick pjf at perltraining.com.au
Mon Jan 30 18:38:21 PST 2006


G'day Raphael,

Raphael Alla wrote:

> my query was actually generated from the material coming from your own web
> site! I think I understand better the security issues now.

Good... I hope...  ;)  Would this be from our sample chapter from the Perl
Security course?  The one that discusses that if you turn off strict then taint
mode won't save you from calling subroutines by symbolic reference?

> Solution 1: use a namespace convention such as
> 
> &("namespace_name_" . $sub}();
> 
> But this leaves the call by reference.

Indeed, and if 'namespace_name' is a package (the most obvious choice) there's
still a risk that a module that has been use'd has exported subroutines into
that package.

> Solution 2: Use tags to flag which one are the subs which can be called from
> the outside and build the hashtable "on the fly" at execution time. This
> seems to be similar to what Catalyst does.

[snip]

The trouble here is making it 'obviously correct'.  Luckily, using
Attribute::Handlers is a good way of going about this.  Attribute::Handlers
allows you to write subroutines which will then act when something with that
attribute is declared.

The following *untested* code, with no warranty, provides an example of how we
can catch all subroutines declared with the 'Callable' attribute, and add them
to a hash of (name => coderef) pairs.

#!/usr/bin/perl -w
use strict;

use Attribute::Handlers;

my %callable;

# Remember subroutines marked as 'Callable' and place them into the
# %callable hash declared above.  This code does *not* examine the package
# into which such subroutines are declared.  $_[0] contains the package
# name if this is required.

sub Callable :ATTR {
	my (undef, $glob, $sub_ref, undef, undef, undef) = @_;

	if (ref($sub_ref) ne 'CODE') {
		croak q{'Callable' attribute set on non-subroutine};
	}

	if ($glob eq 'ANON') {
		croak q{'Callable' attribute set on anonymous subroutine};
	}

	# Find the name of the subroutine (technically the typeglob
	# it was entered into).  Note this does not provide the package
	# name.

	my $name = *{$glob}{NAME}
		or die "Internal error: subroutine with no name";

	# Now plug our name -> coderef into our hash.

	$callable{$name} = $sub_ref;

	return;

}

__END__

Cheerio,

	Paul

-- 
Paul Fenwick <pjf at perltraining.com.au> | http://perltraining.com.au/
Director of Training                   | Ph:  +61 3 9354 6001
Perl Training Australia                | Fax: +61 3 9354 2681


More information about the Melbourne-pm mailing list