Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

use of Safe module

by iaw4 (Monk)
on Jan 02, 2012 at 19:53 UTC ( [id://945960]=perlquestion: print w/replies, xml ) Need Help??

iaw4 has asked for the wisdom of the Perl Monks concerning the following question:

Dear perlmonks---this is an indirect followup question to my need to write a safe mini interpreter. I want to figure out how module Safe works. the problem is that I want web user A to enter questions that web user B should answer. I need to avoid web user A doing mischief. This is easier to explain with an example:
#!/usr/bin/perl -w use strict; use Safe; my $secret="my-password-should-never-be-shown\n"; ## the following are lines that a web user could try to pass to my pro +gram my $_ = <<HEREDOC; sub round { return sprintf("%.\$_[1]f", \$_[0]); } ; my \$in=rand(); m +y \$answer=(\$in+log(10)); print "what is \$in+log(10)?\\n"; round(\$ +answer,3) ## this should evaluate just fine print \$secret; ## yikes, sho +uld be an error system("ls") ## yikes, sho +uld be an error `ls` ## yikes, sho +uld be an error open(FIN, ">", "really-bad-to-write-to-fs") ## yikes, sho +uld be an error HEREDOC foreach (split(/\n/, $_)) { print "\n----------------\nExecuting '$_'\n\n"; # this executes everything blindly and is a really bad idea my $result=eval($_); print "UNSAFE '$_'\n\t\t-> ".($result||"undef")."\n\n\n"; # this does not do what I had hoped it to do # I want the first line be executed, and all other lines to be trapp +ed. my $compartment= new Safe; $result= $compartment->reval("$_"); print "SAFE '$_'\n\t\t-> ".($result||"undef")."\n\n\n"; }

Unfortunately, my reval does not execute anything. is there a set of ops that are what I should open up to allow exactly and only what I used in the first line?

Advice appreciated.

Replies are listed 'Best First'.
Re: use of Safe module
by Anonymous Monk on Jan 02, 2012 at 20:47 UTC

    Advice appreciated.

    Um, you never permit anything, did you see the synopsis ?

    #!/usr/bin/perl -- use strict; use warnings; use Safe; my $secret = "my-password-should-never-be-shown\n"; local $ENV{secret} = $secret ; my @commands = ( q{sub round { return sprintf( "%.$_[1]f", $_[0] ); } my $in = rand(); my $answer = ( $in + log(10) ); print "what is $in+log(10)?\n"; round( $answer, 3 ); ## this should evaluate just fine }, q{ print $secret; ## yikes, should be an error }, q{ $secret }, q{ $ENV{secret} }, q{ $$ }, q{ system("ls") ## yikes, should be an error }, q{ `ls` ## yikes, should be an error }, q{ open( FIN, ">", "really-bad-to-write-to-fs" ) ## yikes, shou +ld be an error }, ); for my $command ( @commands ){ print "\n#### code start \n$command\n#### code end\n"; { my $compartment = new Safe; #~ $compartment->permit(qw/ :base_core :base_mem :base_io /); + #no #~ $compartment->permit(qw/ :base_math sprintf print /); # yes $compartment->permit(qw/ :base_math :base_core :base_mem :base +_io /); # ues my $result = $compartment->reval( $command ); print " $compartment => ".($result||"undef")."\n############\n +\n"; } } __END__ #### code start sub round { return sprintf( "%.$_[1]f", $_[0] ); } my $in = rand(); my $answer = ( $in + log(10) ); print "what is $in+log(10)?\n"; round( $answer, 3 ); ## this should evaluate just fine #### code end what is 0.5277099609375+log(10)? Safe=HASH(0x99a4ac) => 2.830 ############ #### code start print $secret; ## yikes, should be an error #### code end Safe=HASH(0x99a48c) => 1 ############ #### code start $secret #### code end Safe=HASH(0xa2ad64) => undef ############ #### code start $ENV{secret} #### code end Safe=HASH(0xb10754) => undef ############ #### code start $$ #### code end Safe=HASH(0xb16374) => undef ############ #### code start system("ls") ## yikes, should be an error #### code end Safe=HASH(0xb105f4) => undef ############ #### code start `ls` ## yikes, should be an error #### code end Safe=HASH(0xb10114) => undef ############ #### code start open( FIN, ">", "really-bad-to-write-to-fs" ) ## yikes, should be +an error #### code end Safe=HASH(0xa628f4) => undef ############

      thank you. this is exactly what I needed. I suspected something like this. the problem I had was that I did not see a list with explanation that showed and recommended what the set of ':permit'-table items would be/should be.

      your example solution is great.

      /iaw

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://945960]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2024-04-26 03:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found