Code Injection with eval require

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.)

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

sponsored by the How to Make a Smoothie guide

Categories

Pages

About this Entry

This page contains a single entry by chromatic published on October 3, 2012 10:54 AM.

The Overhead of a Class was the previous entry in this blog.

Solitude is a Drawback of Perl Productivity is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.


Powered by the Perl programming language

what is programming?