|
|
Subscribe / Log in / New account

dash/ash

dash/ash

Posted Oct 2, 2014 8:31 UTC (Thu) by ibukanov (subscriber, #3942)
In reply to: dash/ash by wahern
Parent article: Bash gets shellshocked

> Why not just switch to Perl, for example?

Perl is not particularly safer with syntax that is similar in complexity to Bash. Besides, the shellshock comes not from the syntax but from a badly designed Bash feature that could be provided for "convenience" just as well in Perl or Python or JavaScript under node.js.


to post comments

dash/ash

Posted Oct 2, 2014 9:41 UTC (Thu) by niner (subscriber, #26151) [Link] (7 responses)

Perl has use strict;
Perl does not mix program code with data.
Perl has a taint mode that catches many cases of missing input sanitation.
Perl's system() function only ever invokes /bin/sh if the given command contains shell metacharacters and supports the system PROGRAM LIST form that never ever invokes a shell (it uses exec()) at all and avoids many errors with missing parameter quoting.

So I'd argue that it is much easier to program safely in Perl than in Bash.

dash/ash

Posted Oct 2, 2014 15:54 UTC (Thu) by ibukanov (subscriber, #3942) [Link] (6 responses)

> it is much easier to program safely in Perl than in Bash.

I want to repeat that Shellshock has nothing to do with programming style of Bash scripts. It comes from a badly designed and implemented feature of the Bash interpreter that is written in C. Perl runtime could just as easily provide a similar "feature" affecting any Perl script, strict or not. For example, can you with certainty assert that Perl interpreter has no bugs related to reading of environment variables that could trigger execution of arbitrary Perl code?

dash/ash

Posted Oct 2, 2014 17:31 UTC (Thu) by dskoll (subscriber, #1630) [Link] (3 responses)

Perl runtime could just as easily provide a similar "feature" affecting any Perl script, strict or not.

But it doesn't. Well, with one exception: Setting PERL5DB will make perl execute arbitrary Perl code, but only if it has been invoked with the "-d" command-line flag which says to run under a debugger, and no Perl script uses that flag.

Perl makes environment variables available in the %ENV hash, but certainly doesn't try to interpret them as Perl code (modulo the single exception above.)

dash/ash

Posted Oct 5, 2014 20:15 UTC (Sun) by alankila (guest, #47141) [Link] (2 responses)

Environment variable PERL5INC would allow specifying library paths that Perl will look into first. If an attacker can control files in the system, then he can probably control the Perl interpreter through setting PERL5INC into suitable target path, and then PERL5OPT to load it.

Thankfully, none of this is even close to as bad as what bash did.

dash/ash

Posted Oct 7, 2014 14:35 UTC (Tue) by dskoll (subscriber, #1630) [Link] (1 responses)

PERL5LIB and PERL5INC are not used in taint mode. Bash really needs a taint mode.

dash/ash

Posted Oct 7, 2014 17:31 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

Bash needs an overlay:
 _____________________________________________ 
/ It looks like your script is over 100 lines \
\ long; did you mean to write this in Perl?   /
 --------------------------------------------- 
    \
     \
                                   .::!!!!!!!:.
  .!!!!!:.                        .:!!!!!!!!!!!!
  ~~~~!!!!!!.                 .:!!!!!!!!!UWWW$$$ 
      :$$NWX!!:           .:!!!!!!XUWW$$$$$$$$$P 
      $$$$$##WX!:      .<!!!!UW$$$$"  $$$$$$$$# 
      $$$$$  $$$UX   :!!UW$$$$$$$$$   4$$$$$* 
      ^$$$B  $$$$\     $$$$$$$$$$$$   d$$R" 
        "*$bd$$$$      '*$$$$$$$$$$$o+#" 
             """"          """"""" 

dash/ash

Posted Oct 2, 2014 21:25 UTC (Thu) by flussence (guest, #85566) [Link] (1 responses)

> Perl runtime could just as easily provide a similar "feature" affecting any Perl script, strict or not.

It's had that feature for decades: 2-arg open() will happily interpret any filename passed to it containing a "|" prefix or suffix to mean a command pipe, and helpfully give the rest of the string to the shell to run. The same function is also used internally to pass filenames in ARGV into the magic <> line-iterator.

dash/ash

Posted Oct 3, 2014 11:23 UTC (Fri) by dskoll (subscriber, #1630) [Link]

2-arg open() will happily interpret any filename passed to it containing a "|" prefix or suffix

That's a little different from the bash bug. It requires the programmer to write a script that doesn't handle user-input safely. It's also stopped in taint mode.

The Bash bug doesn't require any action on the part of the script writer; it happens before your script even has a chance to do anything.

Bash and Perl

Posted Oct 2, 2014 14:59 UTC (Thu) by gwolf (subscriber, #14632) [Link] (1 responses)

Perl's foremost use case is to be a programming language, Bash's is to be a programmable "things" launcher. And of course, while making it easier to be programmed, we have to remember it's still a command-line shell with lots of sugar on top. All of Perl's operations are done within the same process and memory space — Of course, convince perl to eval() or system() or `` your code, and it's game over. But you are very seldom fork()ing inside Perl — And when you do, it's clear to you an external thing is being called.

I do argue (see my above comment) for the utility of some sorts of bashisms, particularly those that help forked process' control and quoting (another favorite of mine is to use $() instead of ``, as it's *way* clearer. I won't argue for using Bash when you use arrays and local scopes — That's a clear indication you should switch to a real programming language. One that, between many other things, separates parsing/compiling from executing, because your program will most likely be complex enough to warrant it!

But yes, people complain about Perl being write-only. Bash constructs and mindset are way worse than Perl.

Bash and Perl

Posted Oct 2, 2014 15:38 UTC (Thu) by madscientist (subscriber, #16861) [Link]

Well, $() is POSIX. And "local" has been proposed for inclusion in POSIX sh and found to be generally available, in some form, in most sh implementations already.

As others have pointed out, if you want to write bash scripts that's fine and it's trivial to do: just start your script with #!/bin/bash. If you want to write POSIX shell scripts, start your script with #!/bin/sh. If you use #!/bin/sh and you use bash-isms, your script is simply wrong.

dash/ash

Posted Oct 9, 2014 11:30 UTC (Thu) by ssokolow (guest, #94568) [Link]

That sort of thing is why I encourage friends who are launching child processes to do their scripting in Python using the subprocess module.

They really did a great job on designing its API... especially when paired with various other modules already part of stdlib.

  1. It's guaranteed to execvp() the requested binary directly without shell indirection unless you explicitly use shell=True
  2. Any necessary argument parsing and expansion can be done without arbitrary code execution by using shlex.split(), os.path.expanduser(), fnmatch.filter(), glob.glob() modules from the Python standard library.
  3. Quoted strings can still be handled safely by using shlex to explicitly perform argument splitting without code execution before using subprocess.
  4. The env argument makes it easy to call a subprocess with a sanitized environment.
  5. The cwd argument avoids the need for cding in os.system() or doing an os.getcwd() os.chdir() dance.

Apparently someone's also ported it to ruby though, unfortunately, it's not part of stdlib there and I don't know whether shlex is also available.

Plus, of course, convenience functions like subprocess.call(), subprocess.check_call(), and subprocess.check_output() integrate nicely with the mix of try/except/finally and os.walk() I already recommend for that sort of scripting.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds