Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Tue, 10 Nov 2020 20:48:21 -0800
From: Eric Pruitt <eric.pruitt@...il.com>
To: oss-security@...ts.openwall.com
Subject: Dash executes code when noexec ("-n") is specified

I emailed security@...ian.org a couple of weeks ago about an issue with
Dash executing code when I wouldn't expect it to based on its
documentation and the POSIX spec, but I didn't get a response, so I'm
posting the message here in hopes of getting another opinion:

Most UNIX shells support "-n" / noexec which should syntax check scripts
without executing them, but Dash will execute code anyway in some
contexts:

    $ dash -n -c 'echo this should not be executed'
    this should not be executed

Interestingly, it does not execute code that gets piped in:

    $ echo 'echo this should not be executed' | dash -n
    $

In discussing "set -n" / noexec, POSIX 2018
(https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set)
states "The shell shall read commands but does not execute them; this
can be used to check for shell script syntax errors. An interactive
shell may ignore this option," and I did not find anything in the Dash
manual that would suggest this is intentional:

    $ man dash | fgrep -C2 noexec
               -f noglob        Disable pathname expansion.

               -n noexec        If not interactive, read commands but do
                                not execute them.  This is useful for
                                checking the syntax of shell scripts.

Maybe this is an issue with how Dash determines whether its being
executed interactively, but even if I try redirecting file descriptors
so none of them point to a TTY, the code still gets run:

    $ ls -l
    total 0
    $ dash -n -c 'touch script_was_executed' < /dev/null >/dev/null 2>&1
    $ ls -l
    total 0
    -rw------- 1 ericpruitt ericpruitt 0 Oct 28 17:22 script_was_executed
    $

None of the other shells I tested exhibit this:

    $ ksh -n -c 'echo this should not be executed'
    $ mksh -n -c 'echo this should not be executed'
    $ zsh -n -c 'echo this should not be executed'
    $ bash -n -c 'echo this should not be executed'
    $

This has the potential to be a security hazard because programs could
unintentionally execute arbitrary code. I discovered this while helping
someone with a test framework in which I suggested implementing shell
script syntax checking as part of validating some configuration files
that contain short Bash and Dash scripts (e.g. Cron jobs). Had this
issue not been discovered, it's possible the build system would've
inadvertently executed code I only wanted to syntax check.

Can you confirm whether or not this behavior is expected?

Thanks,
Eric

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.