http://www.perlmonks.org?node_id=151604

Hello,

I sometimes use Data::Dumper to pass "objects" over the network. Yeah, I know about
Storable, but I rather like Data::Dumper for the text readability. I ran across this
article by Randal Schwartz (merlyn), and that got me to thinking harder about the security.
I already use Safe.pm to cage the eval, but I couldn't help but develope a sense of
paranoia over that being enough. Undumper (from the link above) seemed a strange way
of going about it to me, so I decided to investigate Safe's ability to limit opcodes.
The result is the code below.
Criticisms not only welcomed, but appreciated.

Warning: This code has not been thoroughly reviewed by a security expert. Therefore,
it would be foolish for you to use it in any way without knowing what you
are doing.

Update: Added 'rv2gv', 'null' and 'undef' to defaults.

Update 2: This code is crap. Don't use it at all.
Data/Revive.pm
package Data::Revive; # This is (hopefully) the bare minimum of opcodes # necessary to use normal objects. # Pass in "-opcode" to disable any default opcode, # or any opcode not listed here to enable it. my @defaults = qw { const rv2sv rv2av rv2hv rv2gv pushmark anonlist anonhash refgen sassign leaveeval padany aelem helem null undef }; sub revive_object { my $object_text = $_[0]; my @options = @{ $_[1] or [] }; my @allowed_ops = grep { defined } grep !/^-/, ( @options, grep { my $this = $_; not grep /^-$this$/, @options } @defaults ); use Safe; my $safe_env = Safe->new(); $safe_env->permit_only(@allowed_ops); my $obj = $safe_env->reval($object_text) or die $@; if ((grep /^bless$/, @allowed_ops) and ref($obj)) { # Safe's restricted environment causes blessed objects to # lose their 'magic' when passed back out. Here we simply # re-bless the object to correct that. bless $obj, ref($obj); } return $obj; } 1;

revive_test.pl
#!/usr/bin/perl use strict; use Data::Revive; package Nothing; sub foo { print "foo method called\n"; } package main; use Data::Dumper; $Data::Dumper::Purity = 1; print "--- Test Object ---\n"; my $sample_obj = { 'foo' => { 'bar' => [0,1,2,3,4] }, 'baz' => 12, 'quux' => "string", 'quuux' => undef }; $sample_obj->{quuuux} = $sample_obj; my $sample_text = Dumper($sample_obj); print $sample_text; print "\n\n"; print "--- Revived Object ---\n"; my $loaded_obj = Data::Revive::revive_object($sample_text); print Dumper($loaded_obj); print "\n\n"; print "--- Revived Object with added Opcode ---\n"; my $sample_text2 = Dumper(bless($sample_obj, 'Nothing')); my $loaded_obj2 = Data::Revive::revive_object($sample_text2, [qw(bless +)]); print Dumper($loaded_obj2); $loaded_obj2->foo(); print "\n\n"; print "--- Revived Object with (intentional) failed Opcode ---\n"; # note, bless not allowed this time $loaded_obj2 = Data::Revive::revive_object($sample_text2); print Dumper($loaded_obj2); print "\n\n";

Replies are listed 'Best First'.
Re: (Yet Another) Safely eval Data::Dumper objects module
by premchai21 (Curate) on Mar 14, 2002 at 19:44 UTC
Re: (Yet Another) Safely eval Data::Dumper objects module
by Felonious (Chaplain) on Mar 14, 2002 at 05:37 UTC
    Sorry, still haven't gotten the hang of posting links yet. The article I tried to reference above is located at http://www.linux-mag.com/2001-10/perl_01.html if you are interested.

    Update: Fixed the link in the main article

    -- O thievish Night, Why should'st thou, but for some felonious end, In thy dark lantern thus close up the stars? --Milton