What's wrong with this code?
package Some::Loader;
use strict;
use warnings;
sub import
{
my $class = shift;
for my $module (@_)
{
eval "require $module;"
}
}
1;
See it yet? Here's a hint: what can $module
contain?
Still don't see it? Run this command line:
$ perl -MSome::Loader='vars; exit' -E 'say "Hello, world!"'
For more fun, export the environment variable PERL5OPT
.
(Yes, everyone knows that if you don't have control over the environment
variables set on your machine you can do a lot of damage, but do you check all
of the software you install for changes to every place where your environment
can possibly come from? It's not just PERL5OPT
that's the problem
either.)
If you're passing arbitrary external data to eval
STRING, you
might execute code. At least consider using something like Module::Runtime's
require_module()
to load modules dynamically, as that distribution
checks the sanity of data passed to verify that it's receiving something that
looks like a module name and not an arbitrary Perl expression.
After all, you wouldn't pass arbitrary user data to a SQL statement without using placeholders, would you? (Oh wait, the Perl documentation recommends this idiom on the assumption that if you use it, any security problems are your own fault, you poor deluded fool.)