scalar to method name

O

Oobi Van Doobi

hi
need some advice. I have an xml source, which includes names of modules and
methods in the modules. For example

<action>
<module>
some_module
</module>
<method>
some_method
</method>
</action>

now, I need to be able to execute some_module::some_method. The problem is
that the names are scalars, and I want to convert the scalars to code
"names".

As for now I have the names of module and method as:
\&{$module::$method}.
But, trying to execute the above I get errors.
What is the correct way of doing this?

thank's.
 
A

anno4000

Oobi Van Doobi said:
hi
need some advice. I have an xml source, which includes names of modules and
methods in the modules. For example

<action>
<module>
some_module
</module>
<method>
some_method
</method>
</action>

now, I need to be able to execute some_module::some_method. The problem is
that the names are scalars, and I want to convert the scalars to code
"names".

"Code name" is not a recognized term in Perl. What are you trying
to create?
As for now I have the names of module and method as:
\&{$module::$method}.

That looks like a failed attempt to create a coderef to the given
sub.
But, trying to execute the above I get errors.

Oh please. *What* errors do you get? Just because you can't be
bothered to paste the error message every reader of your post has
to make up code (which may or may not be the exact code that you
ran) to see what the error is.
What is the correct way of doing this?

What is "this"? You can get a code ref to the given method through

my $methref = \ &{ $module . '::' . $method};

provided the sub exists in the package. But calling a coderef as a
method, as in "$obj->$methref", while calling your code, won't do
inheritance. It's not an actual method call.

You can call a method whose name you have in $method (as above)
simply as

$obj->$method( @args);

provided $obj is an object of the right class. You can also call it
as a class method through

$module->$methods( @args);

If that is what you want to do, no conversion to a "code name" is
necessary, you can use the strings as given.

Plea'se.

Anno
 
B

Brian McCauley

$obj->$method( @args);

Be aware that malicious input may be able to exploit this because
$method can be any fully qualified function an not necessarily a method
of the class of $obj.
 
A

anno4000

Brian McCauley said:
Be aware that malicious input may be able to exploit this because
$method can be any fully qualified function an not necessarily a method
of the class of $obj.

That's true, but how is it relevant? The expression contains three
variables, each of which could be user-determined and have malicious
content. Just how malicious it could get can't be determined without
knowing which subs and methods exist in the environment and also which
freedom, if any, the user has in determining the variables.

Why does $method need special attention?

Anno
 
R

Randal L. Schwartz

anno4000> That's true, but how is it relevant? The expression contains three
anno4000> variables, each of which could be user-determined and have malicious
anno4000> content. Just how malicious it could get can't be determined
anno4000> without knowing which subs and methods exist in the environment and
anno4000> also which freedom, if any, the user has in determining the
anno4000> variables.

anno4000> Why does $method need special attention?

Because Perl got a black eye because SOAP::Lite permitted an exploit
permitting anyone to run any command they chose if they had implemented *any*
web service with SOAP::Lite. Ouch. And this was the vector.

That's the kind of thing those of us in the core Perl community don't quickly
forget, so if we seem a bit gunshy about a certain construct, it's with
reason.

print "Just another Perl hacker,"; # the original
 
A

anno4000

Randal L. Schwartz said:
anno4000> That's true, but how is it relevant? The expression contains three
anno4000> variables, each of which could be user-determined and have malicious
anno4000> content. Just how malicious it could get can't be determined
anno4000> without knowing which subs and methods exist in the environment and
anno4000> also which freedom, if any, the user has in determining the
anno4000> variables.

anno4000> Why does $method need special attention?

Because Perl got a black eye because SOAP::Lite permitted an exploit
permitting anyone to run any command they chose if they had implemented *any*
web service with SOAP::Lite. Ouch. And this was the vector.

That's the kind of thing those of us in the core Perl community don't quickly
forget, so if we seem a bit gunshy about a certain construct, it's with
reason.

Still it isn't the construct per se that's dangerous. Allowing
insufficiently controlled input to be used in a program is dangerous.
It may be more critical in some constructs than others, but it shouldn't
be the construct but the fact that a variable with uncontrolled content
is used *anywhere* that triggers an alert.

Only the OP knows the origin of the xml(?) file the variable is read
from. It may be as safe as the program source.

Anno
 
P

Peter J. Holzer

Still it isn't the construct per se that's dangerous. Allowing
insufficiently controlled input to be used in a program is dangerous.
It may be more critical in some constructs than others, but it shouldn't
be the construct but the fact that a variable with uncontrolled content
is used *anywhere* that triggers an alert.

You have to use a variable with uncontrolled content *somewhere* if you
want to write useful programs in the real world. Almost any input to a
program is outside of the control of the programmer and very often
outside of the control of the person running the program. Yet the
program has to deal with such data. An alert on any use of such data
would not be useful. Some operations on the data are safe: E.g.,
matching a regexp against it, or writing it to a file. Others are unsafe
(e.g. open or eval).

Taint checking tries to distinguish between safe and unsafe operations.

That said, I wonder why taint checking doesn't catch this (at least with
perl 5.8.8)?


#!/usr/local/bin/perl -T
use warnings;
use strict;

my $x = X->new();
my $m = $ARGV[0];

$x->$m();

package X;
sub new {
my ($class) = @_;
my $self = {};
bless $self, $class;
return $self;
}

sub foo {
print "foo\n";
}

sub bar {
print "bar\n";
}

package Y;

sub gazonk {
print "gazonk\n";
}

hp
 
A

anno4000

Peter J. Holzer said:
You have to use a variable with uncontrolled content *somewhere* if you
want to write useful programs in the real world. Almost any input to a
program is outside of the control of the programmer and very often
outside of the control of the person running the program. Yet the
program has to deal with such data. An alert on any use of such data
would not be useful. Some operations on the data are safe: E.g.,
matching a regexp against it, or writing it to a file. Others are unsafe
(e.g. open or eval).

Taint checking tries to distinguish between safe and unsafe operations.

Well, there you are. When the program needs taint checking, treat
*every* content that doesn't come from the source as suspect. This
is exactly what taint checking tries to do, though not always perfectly
as your example below (now snipped) shows. Thus the problem can be
reduced to deciding whether a program needs taint checking.

I don't have a pat answer to that, though I think programmers develop
a reliable intuition in that respect. The question can't be decided
by looking at the program alone. Many programs assume to be run
from a shell and unconcernedly open and overwrite files given as
parameters. The user can do any damage within permissions, but
they can do that anyway through the shell. The same program, run
with parameters not from the command line but some, well, "foreign"
source, might need taint checking and other precautions. What exactly
constitutes "foreign" I find hard to define but easy to know when
I see it. Then, I'm nobody's security engineer, I'm not paid
to think about this stuff :)

Anno
 
P

Peter J. Holzer

Well, there you are. When the program needs taint checking, treat
*every* content that doesn't come from the source as suspect.

Yes, every content from untrusted sources is suspect, but not every
operation on suspect content is unsafe. I think I (and probably Randal)
misunderstood your question "Why does $method need special attention?"

To recap, the code in question was $obj->$method(@args).

I understood your question as "why does calling a method with a user
supplied name need special attention?" and the reason has been explained
by Randal: You cannot call only methods of $obj's class but arbitrary
objects that way. So if you want to restrict the user to call only
$obj's class you have to check $method before the call.

OTOH, calling a method with unchecked arguments is not inherently
unsafe: The method can (and should) check the arguments.

This is exactly what taint checking tries to do, though not always
perfectly as your example below (now snipped) shows. Thus the problem
can be reduced to deciding whether a program needs taint checking.

I was assuming a context which needs taint checking. Otherwise its
perfectly fine if you can call arbirtrary methods.

I don't have a pat answer to that, though I think programmers develop
a reliable intuition in that respect. The question can't be decided
by looking at the program alone.

Right. The question can be decided by looking at the context in which
the program is executed: If the entity running the program does not
completely trust the entities supplying the input data, the data has to
be checked (that doesn't mean taint checking is needed: Taint checking
is just a tool to help the programmer to find places where he needs to
add checks).

Examples:

* A web server: Everybody can send arbitrary data to it. Clearly it
needs to check its input.

* A script invoked by a user on data which he has written himself: Input
checking should not be necessary, the user presumably trusts himself.
In reality, some input checking is still necessary, because the user
may have violated some assumptions that the programmer made: For
example, the programmer may have foolishly assumed that a filename
doesn't contain spaces. If he did that, he'd better check it, because
users will create filenames with spaces if they can.

* A script invoked by a user on data which he obtained from an untrusted
source (e.g., downloaded from a website, or received via email): Input
checking is necessary.

Which checks are necessary also depends on context. For simple

hp
 
A

anno4000

Peter J. Holzer said:
Yes, every content from untrusted sources is suspect, but not every
operation on suspect content is unsafe. I think I (and probably Randal)
misunderstood your question "Why does $method need special attention?"

To recap, the code in question was $obj->$method(@args).

I understood your question as "why does calling a method with a user
supplied name need special attention?" and the reason has been explained
by Randal: You cannot call only methods of $obj's class but arbitrary
objects that way. So if you want to restrict the user to call only ^^^^^^^
methods

$obj's class you have to check $method before the call.

OTOH, calling a method with unchecked arguments is not inherently
unsafe: The method can (and should) check the arguments.

I isn't always immediately obvious what is safe. Take $obj in the
expression above. If what the user can put there is always an object
of an expected class, all is fine. If the user has a way to put an
arbitrary string there, methods in unexpected classes can be called
(as class methods).
I was assuming a context which needs taint checking. Otherwise its
perfectly fine if you can call arbirtrary methods.


Right. The question can be decided by looking at the context in which
the program is executed: If the entity running the program does not
completely trust the entities supplying the input data, the data has to
be checked (that doesn't mean taint checking is needed: Taint checking
is just a tool to help the programmer to find places where he needs to
add checks).

That leaves "entity" and "trust" to be defined.

Anno
 
D

Dr.Ruud

Oobi Van Doobi schreef:
I have an xml source, which includes names of
modules and methods in the modules. For example

<action>
<module>
some_module
</module>
<method>
some_method
</method>
</action>

now, I need to be able to execute some_module::some_method. The
problem is that the names are scalars, and I want to convert the
scalars to code "names".

As for now I have the names of module and method as:
\&{$module::$method}.
But, trying to execute the above I get errors.
What is the correct way of doing this?

Use a hash.
 
C

Charles DeRykus

Randal said:
anno4000> That's true, but how is it relevant? The expression contains three
anno4000> variables, each of which could be user-determined and have malicious
anno4000> content. Just how malicious it could get can't be determined
anno4000> without knowing which subs and methods exist in the environment and
anno4000> also which freedom, if any, the user has in determining the
anno4000> variables.

anno4000> Why does $method need special attention?

Because Perl got a black eye because SOAP::Lite permitted an exploit
permitting anyone to run any command they chose if they had implemented *any*
web service with SOAP::Lite. Ouch. And this was the vector.
...

(RPC::XML was similarly afflicted and was also patched)

I see an URL (unfortunately 404) in a recent SOAP::Lite version:

# check to avoid security vulnerability:
Protected->Unprotected::method(@parameters)
# see for more details: http://www.phrack.org/phrack/58/p58-0x09 <--
die "Denied access to method ($method_name)\n"
unless $method_name =~ /^\w+$/;

Anyone know if the details are still available somewhere...
 
R

Randal L. Schwartz

anno4000> I isn't always immediately obvious what is safe. Take $obj in the
anno4000> expression above. If what the user can put there is always an object
anno4000> of an expected class, all is fine. If the user has a way to put an
anno4000> arbitrary string there, methods in unexpected classes can be called
anno4000> (as class methods).

No, what we keep saying (and perhaps you keep missing) is that even if $obj is
an expected object, $method can be an *ARBITRARY SUBROUTINE NAME*, defined
ANYWHERE IN THE GLOBALS.

That is, given:

$y = "Foo::Bar";
$x->$y(@z);

You will get a call to Foo::Bar($x, @z) (unless Foo::Bar doesn't exist). The
class of $x does not need to have anything to do with Foo::Bar.

This means that it's not enough to know that $x is a trusted object. The
string $y also must be vetted. This is the hole that was exploited, because
most people don't get this (perhaps even you since you seem to keep thinking
it's no big deal).

If that was clear to you already, your messages in response did not
acknowledge this danger. If that *wasn't* clear to you, I hope you now see
the danger that even people of reasonable intelligence didn't see this one
coming.

print "Just another Perl hacker,"; # the original
 
A

anno4000

Randal L. Schwartz said:
anno4000> I isn't always immediately obvious what is safe. Take $obj in the
anno4000> expression above. If what the user can put there is always an object
anno4000> of an expected class, all is fine. If the user has a way to put an
anno4000> arbitrary string there, methods in unexpected classes can be called
anno4000> (as class methods).

No, what we keep saying (and perhaps you keep missing) is that even if $obj is
an expected object, $method can be an *ARBITRARY SUBROUTINE NAME*, defined
ANYWHERE IN THE GLOBALS.

Yes, I'm quite aware of that. I use "$obj->Class::meth()" quite a bit.
My point (if I may call it that) is that other parts of the expression
can be (or definitely are) sensitive too.

In the snippet

$obj->$method( @args)

clearly $method is the most sensitive variable. However, as pointed
out elsewhere, if the user has a way to deposit an arbitrary class
name (instead of a blessed object) into $obj (or an object blessed into
an unexpected class), unexpected code could be called too, though not
as freely as through $method.
If that was clear to you already, your messages in response did not
acknowledge this danger. If that *wasn't* clear to you, I hope you now see
the danger that even people of reasonable intelligence didn't see this one
coming.

Given in isolation the danger is easy to spot. That's why I didn't
think an explicit acknowledgement was necessary. It's harder when
(say) $object has been copied and handed around a lot so only taint
knows that it may be suspect, and also when the critical line is one
of a few thousand.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,048
Members
47,651
Latest member
VeraPiw932

Latest Threads

Top