Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

perl -s is evil?

by malloc (Pilgrim)
on Nov 15, 2001 at 05:14 UTC ( [id://125480]=perlmeditation: print w/replies, xml ) Need Help??

Monks, I was playing around with perl -s today, trying to come up with an obfu, and i realized that it allows you to modify read only variables Now I am hoping that perl scopes the vars off of the command line differently, localizes them somehow, but it still makes for some SURPRISING RESULTS. As an example, the below code, (perl 5.6.1 i386 Linux) when run with no command line options, prints "got password = hello", but when run with the command line switch "-1=foo", it prints "got password=foo"!!!! Doesn't this seem dangerous? Is this acceptable behavior? I would love some input on this:
#! /usr/bin/perl -ws use strict; my $test = "hello"; $test =~ m/(.*)/; print "got password = $1\n\n";

Thanks a lot,
-malloc

"LISP programmers know the value of everything, and the cost of nothing"

UPDATE: I also just tested that i can remove the -s from the script, then just run it with "perl -s scrip.pl -1=foo" and the hackish behavior still works, so this seems to be a vulnerability whether you use -s or not?

Replies are listed 'Best First'.
Re: perl -s is evil?
by blakem (Monsignor) on Nov 15, 2001 at 05:52 UTC
    Yes, -s is very bad, but I hadn't realized just how bad until you posted this.... Among the many globals that I could tweak with -s were $< $> $) and $( which should raise a huge security flag for anyone whos read perlvar. For instance, when saved as evildashs.pl, and envoked as:

    % ./evildashs.pl -\<=0 -\>=0 -\(=0 -\)=0

    The following code might raise some eyebrows....

    #! /usr/bin/perl -wsT use strict; print "\$) = ", $), "\n"; print "\$( = ", $(, "\n"; print "\$< = ", $<, "\n"; print "\$> = ", $>, "\n"; __END__ =head1 OUTPUT $) = 0 $( = 0 $< = 0 $> = 0
    I don't think this actually gives the process any new powers, but it would allow someone to execute code that was only supposed to be invoked as root.

    Oh, right. I should include the obligatory link to Getopt::Std and Getopt::Long for a much better way to handle command line options.

    -Blake

      Of course Getopt::* isn't actually a solution either. One could simply do perl -s ./IUseGetOptToAvoidEvilDashes.pl -\<=0 -\>=0 -\(=0 -\)=0

      But I agree it is disconcerting, though I wouldn't go so far as to call -s evil.

      -- perl -p -e "s/(?:\w);(<A HREF="/index.pl?node=st&lastnode_id=2437">st< +/A>)/'\$1/mg"
Re: perl -s is evil?
by grinder (Bishop) on Nov 15, 2001 at 13:58 UTC

    Unfortunately, I can't reproduce your results. I get 'password = hello' no matter what, for the following platforms:

    • 5.005_03 built for i386-freebsd
    • 5.005_03 built for i386-linux
    • v5.6.0 built for i386-openbsd
    • v5.6.0 built for sun4-solaris
    • v5.6.1 built for i386-linux
    • v5.6.1 built for MSWin32-x86-multi-thread

    update: regarding blakem's one-liner, I see "foo" outputted on all the above platforms. So it looks like a bug. I shall have to revise my opinion regarding -s.

    Are you sure that code fragment is what you ran locally? -s isn't that bad. I use it on rare occasions, usually for a short while when a script evolves from needing no command-line switches at all before needing the full-blown mechanism that Getopt::* brings you.

    Others may be interested in a tutorial I wrote on the subject a while back: Parsing your script's command line. (Now revised to point to this thread).

    --
    g r i n d e r
      Here's a one liner that exhibits this oddity... 5.6.1 and 5.00503 on linux:
      perl -sle 'print $1' -- -1=foo foo /usr/local/bin/perl5.6.1 -sle 'print $1' -- -1=foo foo /usr/local/bin/perl5.00503 -sle 'print $1' -- -1=foo foo
      Can you replicate this?

      -Blake

        I can replicate that. But more to the point, I also get the following result which is closer to the original post:

        (using both Perl 5.6.0 on Win95 and Perl 5.005_02 on Solaris)

        % perl -sle '"Hello" =~ /(\w+)/; print $1' -- -1=foo foo
        It's just plain wrong. Not only can $1 be assigned to, but afterward it refuses to take the pattern from the regex.

        buckaduck

      Grinder,
      Just cut and pasted the exact same fragment onto a different linux box and got the exact same results when using "./test.pl -1=foo". Also tested on 5.005_03 built for sun4-solaris. Same thing! What is the disconnect i wonder?
      -malloc
Re: perl -s is evil?
by pileswasp (Monk) on Nov 22, 2001 at 00:10 UTC
    Curiously enough, if you try and use it all (in an == for instance, it reverts back, so it's not as scary as it looks, just a bit buggy:
    #! /usr/bin/perl use strict; print "\$> = ", $>, "\n"; $> == 1000 and warn "eq"; print "\$> = ", $>, "\n";

    perl -Tws evil.pl -\>=0 ouputs:
    $> = 0 eq at evil.pl line 5. $> = 1000

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-03-19 02:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found