Safely eval code from text file--suggestions?

Discussion in 'Perl Misc' started by JS Bangs, Sep 1, 2003.

  1. JS Bangs

    JS Bangs Guest

    All,

    I've got a module that will read an XML file that has code as the
    contents of some elements. I'd like to be able to capture this code as a
    code reference and pass that code reference to a function, without risking
    any internals. The following code works, but doesn't seem foolproof:

    # %code, $self, and $parse defined elsewhere
    if (exists $code{$_}) {
    my $c;
    my $code = '$c = sub {' . $parse->{$_} . '}';

    # Prevent $code from modifying in-scope variables we need to keep
    {
    local($self, $parse);
    eval $code;
    }

    if ($@) {
    err("Errors processing $_ : $@");
    }
    else {
    $self->$_($c);
    }
    }

    Suggestions very welcome.

    --
    Jesse S. Bangs
    http://students.washington.edu/jaspax/
    http://students.washington.edu/jaspax/blog

    Jesus asked them, "Who do you say that I am?"

    And they answered, "You are the eschatological manifestation of the ground
    of our being, the kerygma in which we find the ultimate meaning of our
    interpersonal relationship."

    And Jesus said, "What?"
     
    JS Bangs, Sep 1, 2003
    #1
    1. Advertising

  2. On Sun, 31 Aug 2003 21:55:49 -0700
    JS Bangs <> wrote:
    > I've got a module that will read an XML file that has code as the
    > contents of some elements. I'd like to be able to capture this code
    > as a code reference and pass that code reference to a function,
    > without risking any internals.

    <snip>
    > Suggestions very welcome.


    Correct me if I'm wrong, but you would like to do something like SAX?
    If so, there are some modules to aid you in this on CPAN.

    That's my two cents.

    --
    Jim
    ---
    Copyright notice: all code written by the author in this post is
    considered GPL. http://gnu.org for more information.
    ---
    a real quote ...
    Linus Torvalids: "They are somking crack ...."
    (http://www.eweek.com/article2/0,3959,1227150,00.asp)
    ---
    a fortune quote ...
    "Right now I'm having amnesia and deja vu at the same time." --
    Steven Wright
     
    James Willmore, Sep 1, 2003
    #2
    1. Advertising

  3. In article <>,
    JS Bangs <> wrote:
    >All,
    >
    >I've got a module that will read an XML file that has code as the
    >contents of some elements. I'd like to be able to capture this code as a
    >code reference and pass that code reference to a function, without risking
    >any internals. The following code works, but doesn't seem foolproof:
    >
    ># %code, $self, and $parse defined elsewhere
    >if (exists $code{$_}) {
    > my $c;
    > my $code = '$c = sub {' . $parse->{$_} . '}';
    >
    > # Prevent $code from modifying in-scope variables we need to keep
    > {
    > local($self, $parse);
    > eval $code;
    > }
    >
    > if ($@) {
    > err("Errors processing $_ : $@");
    > }
    > else {
    > $self->$_($c);
    > }
    >}
    >


    Wouldn't you almost certainly want to use the core Safe module
    in case other wickedness creeps into the code...

    HTH,
    --
    Charles DeRykus
     
    Charles DeRykus, Sep 2, 2003
    #3
  4. JS Bangs wrote:
    >
    > All,
    >
    > I've got a module that will read an XML file that has code as the
    > contents of some elements. I'd like to be able to capture this code as a
    > code reference and pass that code reference to a function, without risking
    > any internals. The following code works, but doesn't seem foolproof:
    >
    > # %code, $self, and $parse defined elsewhere
    > if (exists $code{$_}) {
    > my $c;
    > my $code = '$c = sub {' . $parse->{$_} . '}';
    >
    > # Prevent $code from modifying in-scope variables we need to keep
    > {
    > local($self, $parse);
    > eval $code;
    > }
    >
    > if ($@) {
    > err("Errors processing $_ : $@");
    > }
    > else {
    > $self->$_($c);
    > }
    > }
    >
    > Suggestions very welcome.


    use Safe;
    if( exists $code{$_} ) {
    (my $safe = Safe->new)->permit_only(qw:)default));
    my $c = $safe->reval("return sub { $parse->{$_} }");
    if ($@) {
    err("Errors processing $_ : $@");
    } else {
    $self->$_($c);
    }
    }

    [untested; might not *really* be Safe]

    Actually, I know for a fact that in some versions of perl, you can do some
    really odd things in spite of being inside of a Safe object. For example,

    [Windows 95] C:\WINDOWS>perl -MSafe -wle "LOOP: { print 1; Safe->new->reval('last LOOP'); print 2 } print 3"
    1
    Exiting eval via last at (eval 2) line 2.
    Exiting subroutine via last at (eval 2) line 2.
    Exiting eval via last at (eval 2) line 2.
    Exiting subroutine via last at (eval 2) line 2.
    3
    Can't return outside a subroutine.

    Of course, since you've been wholly trusting the contents of $parse->{$_}
    so far (meaning, *anything* could have been done in it's code), you wouldn't
    be doing any *worse* to eval the code inside of a Safe object.

    --
    $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
    );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
    ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
     
    Benjamin Goldberg, Sep 2, 2003
    #4
  5. JS Bangs

    JS Bangs Guest

    Benjamin Goldberg sikyal:

    > use Safe;
    > if( exists $code{$_} ) {
    > (my $safe = Safe->new)->permit_only(qw:)default));
    > my $c = $safe->reval("return sub { $parse->{$_} }");
    > if ($@) {
    > err("Errors processing $_ : $@");
    > } else {
    > $self->$_($c);
    > }
    > }
    >
    > [untested; might not *really* be Safe]


    This works very well. Thank you! I hadn't ever heard of the Safe module
    before, so thanks for pointing this out to me.

    > Of course, since you've been wholly trusting the contents of $parse->{$_}
    > so far (meaning, *anything* could have been done in it's code), you wouldn't
    > be doing any *worse* to eval the code inside of a Safe object.


    Right. I'm actually letting general security issues within the code in
    $parse->{$_} be Somebody Else's Problem. As the module writer, I need to
    make sure that the code doesn't alter the internals of my module, but
    making sure that the code doesn't maliciously use system() calls or do
    other insecure buggery will be the responsibility of the person using the
    module and providing the XML to parse.

    --
    Jesse S. Bangs
    http://students.washington.edu/jaspax/
    http://students.washington.edu/jaspax/blog

    Jesus asked them, "Who do you say that I am?"

    And they answered, "You are the eschatological manifestation of the ground
    of our being, the kerygma in which we find the ultimate meaning of our
    interpersonal relationship."

    And Jesus said, "What?"
     
    JS Bangs, Sep 2, 2003
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric Newton
    Replies:
    3
    Views:
    9,430
    Brock Allen
    Apr 4, 2005
  2. DataBinder.Eval and Eval.

    , Jun 16, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    552
    Karl Seguin [MVP]
    Jun 16, 2006
  3. Bruno Desthuilliers

    eval() == evil? --- How to use it safely?

    Bruno Desthuilliers, Aug 28, 2008, in forum: Python
    Replies:
    17
    Views:
    519
    rustom
    Sep 3, 2008
  4. Steven D'Aprano
    Replies:
    3
    Views:
    1,844
    Jeffrey Straszheim
    Dec 6, 2008
  5. W. Martin Borgert

    Use eval() safely?

    W. Martin Borgert, Feb 21, 2010, in forum: Python
    Replies:
    6
    Views:
    360
    Gregory Ewing
    Feb 25, 2010
Loading...

Share This Page