Discussion:
[ast-developers] Fwd: Arithmetic + array allows for code injection
Irek Szczesniak
2014-05-31 07:48:41 UTC
Permalink
Forwarded conversation
Subject: Arithmetic + array allows for code injection
------------------------

From: Pierre Gaston <pierre.gaston at gmail.com>
Date: Fri, May 30, 2014 at 7:57 PM
To: "bug-bash at gnu.org" <bug-bash at gnu.org>


It doesn't seem right for code looking as innocent as $((a[$i])) or
$((a["$i"])) to allow running arbitrary commands for some value of i, that
are no even that clever:

$ i='$( echo >&2 an arbitrary command )';: $((a["$i"]))
an arbitrary command

$ i='"$( echo >&2 an arbitrary command)"';: $((a[$i]))
an arbitrary command

----------
From: Greg Wooledge <wooledg at eeg.ccf.org>
Date: Fri, May 30, 2014 at 8:08 PM
To: Pierre Gaston <pierre.gaston at gmail.com>
Cc: "bug-bash at gnu.org" <bug-bash at gnu.org>


A workaround is to avoid the explicit $i inside the square brackets:

imadev:~$ i='$(date)'; : $((a[$i]))
bash: Fri May 30 14:05:34 EDT 2014: syntax error in expression (error
token is "May 30 14:05:34 EDT 2014")
imadev:~$ i='$(date)'; : $((a[i]))
bash: $(date): syntax error: operand expected (error token is "$(date)")

I don't dispute the need to fix it, though.


----------
From: Pierre Gaston <pierre.gaston at gmail.com>
Date: Fri, May 30, 2014 at 8:12 PM
To: Greg Wooledge <wooledg at eeg.ccf.org>
Cc: "bug-bash at gnu.org" <bug-bash at gnu.org>


Right, in fact when this bug was found when playing with associative arrays
where this workaround is not possible, with declare -A a you can use
$((${a["$i"]}))

----------
From: Dan Douglas <ormaaj at gmail.com>
Date: Sat, May 31, 2014 at 4:28 AM
To: bug-bash at gnu.org
Cc: Pierre Gaston <pierre.gaston at gmail.com>


The problem is most people don't realize how "variables" are evaluated.
Any time the shell needs to reference a variable, it takes a string
like: "arr[$foo]" and, if there's an index, the string within the index
gets processed for expansions. The arithmetic evaluator is no exception.

The correct way to write such a thing is to let the variable evaluation
expand the parameter from the arithmetic evaluator:

$ bash -c 'typeset -A a; i=\" a[$i]=1+1; echo "$((a[\$i]))"'
2
$ ksh -c 'typeset -A a; i=\" a[$i]=1+1; echo "$((a[\$i]))"'
2
$ zsh -c 'typeset -A a; i=\" a[$i]=1+1; echo "$((a[\$i]))"'
2

Just to clarify, this came up during a discussion in freenode/#ksh (I
believe Jilles Tjoelker first pointed out the issue).

He noticed that ksh93 in some cases allows associative array indexes to
be interpreted differently by the arithmetic evaluator. Namely, if `i=]`
or `i=\"` then ksh uses that value as the index. Bash simply performs
all the usual expansions then takes the resulting string and passes it
to the arithmetic evaluator.

But notice that even ksh processes indexes for expansions. I don't know
why it allows those specific exceptions, and I think I even found a bug
in ksh here.

# Bash is correct here AFAICT.
$ bash -c 'typeset -A a; i="\$(echo \\\")" a[\"]=1+1; echo "$((a[$i]))"'
2

# ksh93 fails this test:
$ ksh -c 'typeset -A a; i="\$(echo \\\")" a[\"]=1+1; echo "$((a[$i]))"'
ksh: syntax error at line 1: `end of file' unexpected

--
Dan Douglas
--
Irek
Loading...