Re: Arbitrary command execution from test on a quoted string
On Fri, Oct 29, 2021 at 1:01 AM elettrino via Bug reports for the GNU Bourne Again SHell wrote: > user@machine:~$ USER_INPUT='x[$(id>&2)]' > user@machine:~$ test -v "$USER_INPUT" > uid=1519(user) gid=1519(user) groups=1519(user),100(users) > What you're doing here, is having the user name a variable, and then testing if that variable is set. I'm not sure if that makes much sense. The user probably doesn't and shouldn't need to know the names of the variables used by the script. It might make more sense to use USER_INPUT as an index to an associative array that was filled with some relevant entries and the user was to pick one. But you still get to watch the quoting: $ declare -A values=([foo]=123 [bar]=345) $ USER_INPUT='x[$(id>&2)]'; test -v 'values[$USER_INPUT]' && echo yes || echo no no $ USER_INPUT='foo'; test -v 'values[$USER_INPUT]' && echo yes || echo no yes (or do the same with [ "${values[$USER_INPUT]+set}" = set ] ) but $ USER_INPUT='x[$(id>&2)]'; test -v "values[$USER_INPUT]" && echo yes || echo no uid=1000(itvirta) gid=1000(itvirta) ... no Not that I'm sure the upper one is still safe against every input. I think issues with associative array keys have been discussed on the list before. I don't know whether this happens with anything other than the -v option > with test; I have not seen it happen under any other circumstance. > Arithmetic expansion is the classic one. Here, we expect the user to give some number and then do arithmetic on it: USER_INPUT='x[$(id>&2)]' a=$(( USER_INPUT + 1 )) # or even: if (( USER_INPUT <= 0 )); then echo invalid input; fi You have to sanitize the inputs, case $USER_INPUT in *[!0-9]*) echo error >&2; exit 1 ;; esac or something like that for the numbers.
Re: Arbitrary command execution from test on a quoted string
On Fri, Oct 29, 2021 at 07:37:13AM +0200, Léa Gris wrote: > A safe way to replace: > test -v "$USER_INPUT" > > Would be: > test "${USER_INPUT@Q}" > > But it is not backward-compatible with older bash versions. test -v is fairly recent as well. That was introduced in 4.2, and the @Q syntax in 4.4. I would suggest a three-step validation: isvar() { [[ $1 = LC_ALL ]] && { test -v "$1"; return; } local LC_ALL=C [[ $1 = [a-zA-Z_]*([a-zA-Z0-9_]) ]] || return 1 test -v "$1" } The forced-on extended globs inside [[ began with 4.1, and test -v in 4.2, so this one requires bash 4.2 just like the original. This one intentionally returns false for subscripted arrays, e.g. isvar 'x[1]'. If you don't like that, change the extended glob to suit yourself. Do note that test -v 'a[i]' requires bash 4.3.
Re: Arbitrary command execution from test on a quoted string
On Fri, Oct 29, 2021 at 12:48:57PM +0300, Ilkka Virta wrote: > Not that I'm sure the upper one is still safe against every input. I think > issues with associative array keys have been > discussed on the list before. Sadly, yes. Bash is the exploding barbed wire death match of programming languages. Every single feature of bash is capable of hurting you if you use it in the naive or obvious way. https://mywiki.wooledge.org/BashProgramming/05#Associative_Array_Index_Multiple_Expansions https://mywiki.wooledge.org/BashPitfalls#pf61 https://mywiki.wooledge.org/BashPitfalls#pf62
Re: Arbitrary command execution in shell - by design!
On 2021/10/29 05:01, Greg Wooledge wrote: On Fri, Oct 29, 2021 at 12:48:57PM +0300, Ilkka Virta wrote: Not that I'm sure the upper one is still safe against every input. I think issues with associative array keys have been discussed on the list before. Sadly, yes. Bash is the exploding barbed wire death match of programming languages. Every single feature of bash is capable of hurting you if you use it in the naive or obvious way. Bash is a command_line console language designed to execute commands locally in the context of the user. Local user access to a console, from a security standpoint, is generally equated with root-access, game over as far as being secure. People have the wrong expectations, if they expect the 'language that allows you all-access to your machine' to be 'secure' when random users are permitted to use it. Perl was developed with features that encompass the commands in shell with facilities (like taint) that help the developer to catch mis-use of raw-environment (including user) input. If you need to develop a script for generic-untrusted third parties, a shell-script of any sort is not a good solution. Shell is good for non-malicious control of local system events. As soon as anyone untrusted can execute a shell script or has generic shell access, you have lost system security. Stop blaming and shaming shell for doing what it was intended to do by using it in a hostile-user environment. If you aren't smart enough to choose the right language for a given purpose, then you need to hire a trained programmer who does. Note -- universities train computer scientists in design -- like collecting requirements (including security) and making decisions for further development. That doesn't mean all graduates are equal. Experience helps, but experience w/o any context in theory, context, and what has been done before is very often wasted. Note -- perl isn't a panacea. It was developed as a tool, but is, in its later life, being randomly changed to suite the wants of its current set of developers (some who think documentation is the same thing as code, and that the perl language should read the documentation of those who write extensions, modules or packages). I wouldn't personally recommend using a perl > 5.16.3, since with 5.18 and above, various incompatibilities with older perls were (and are being) introduced. Also, note, python isn't a shell-scripting language. It may be getting popular, but it was designed more for applications than for operating system control. It's more of a learning-language -- and is being increasing used for such to replace 'pascal' -- another teaching language that has been historically used in schools. But stop thinking bash has security bugs because it lets users (who have shell access and arbitrary root access to their machine to "do things". Because that's what it was designed for. How much lameness Chett has introduced into bash to accommodate the wrong users.
Re: Arbitrary command execution in shell - by design!
On Fri, Oct 29, 2021 at 11:59:02AM -0700, L A Walsh wrote: > How much lameness Chett has introduced into bash to accommodate > the wrong users. This is quite unfair. The major systemic problems with bash (and sh) weren't introduced by Chet Ramey. They've been baked in from the very beginning. Making bash *less horrible* to use for programming purposes doesn't qualify as "lameness" in my book. Even if it does "enable" people to use shells for unsuited purposes, I'd still much rather have indexed and associative arrays (bash) than not have them at all (sh). There are several *suitable* tasks for which they are immensely useful.
Re: Arbitrary command execution in shell - by design!
on 29/10/2021 at 21:33, Greg Wooledge wrote : Making bash *less horrible* to use for programming purposes doesn't qualify as "lameness" in my book. Even if it does "enable" people to use shells for unsuited purposes, I'd still much rather have indexed and associative arrays (bash) than not have them at all (sh). There are several *suitable* tasks for which they are immensely useful. So much good words Greg. And many thanks to you for your valuable Wiki. Thank you for giving credit where credit is due. If you think there might be security concerns, beyond genuine human errors, this is a red flag to avoid shell scripts and find a more suitable language/tool for this task. -- Léa Gris
Re: Arbitrary command execution in shell - by design!
Date:Fri, 29 Oct 2021 11:59:02 -0700 From:L A Walsh Message-ID: <617c4476.2010...@tlinx.org> | Bash is a command_line console language designed to execute commands | locally in the context of the user. Local user access to a console, | from a security standpoint, is generally equated with root-access, | game over as far as being secure. Sorry, but this, and everything that follows from this, is utter nonsense. Once upon a time (back when shells were invented) all command access was via a shell, on the console (not necessarily by a user with root privs, though console access on some systems needed to be restricted for other reasons - depends upon the way the hardware works) or on some other terminal connected to the system. There were no GUIs. There were no terminals capable of displaying anything other that text. In the beginning, all terminals printed on paper. Bash is a (slightly more recent than that, but not all that much) implementation of such a shell (with a whole bunch of extensions added over what was in the initial shells ... some of them, IMO, very useful, some of them a complete waste of space (again, IMO)). Any thought that only root users use shells is simply absurd. | People have the wrong expectations, | if they expect the 'language that allows you all-access to your machine' | to be 'secure' when random users are permitted to use it. The shell is a multi-purpose language - it only allows "all-access" when the privileges of the user permit execution of privileged commands. There is absolutely nothing in the shell itself (including bash and all its extensions, similarly ksh93, or zsh, other wildly extended shells) which grants any kind of privileged access whatever. It is perfectly safe for anyone to run any normal shell script, they cannot do that way anything they could not do any other way. Where there can be issues, is when a script being run by one user accepts input by another (running scripts on one system using data received over a network connection is the obvious example of this, but there are others) is where extreme caution is needed. kre
hash not restored after running command -p
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-a6qmCk/bash-5.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-security uname output: Linux lily 5.4.0-89-generic #100-Ubuntu SMP Fri Sep 24 14:50:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 5.0 Patch Level: 17 Release Status: release Description: I believe there's a bug in bash 4.4 (and still in 5.1) that wasn't there in 4.3.30 When 'command -p' runs, it no longer seems to restore the hash to its previous value. No-bug example from 4.3.30: rsm@lily:~/ash/bash-4.3.30$ echo $BASH_VERSION 4.3.30(1)-release rsm@lily:~/ash/bash-4.3.30$ export PATH= rsm@lily:~/ash/bash-4.3.30$ hostname bash: hostname: No such file or directory rsm@lily:~/ash/bash-4.3.30$ command -p hostname lily rsm@lily:~/ash/bash-4.3.30$ hostname bash: hostname: No such file or directory rsm@lily:~/ash/bash-4.3.30$ Bug example from 4.4: rsm@lily:~/ash/bash-4.4$ echo $BASH_VERSION 4.4.0(1)-release rsm@lily:~/ash/bash-4.4$ export PATH= rsm@lily:~/ash/bash-4.4$ hostname bash: hostname: No such file or directory rsm@lily:~/ash/bash-4.4$ command -p hostname lily rsm@lily:~/ash/bash-4.4$ hostname lily rsm@lily:~/ash/bash-4.4$ # ^ THIS SHOULDN'T HAVE WORKED. rsm@lily:~/ash/bash-4.4$ rsm@lily:~/ash/bash-4.4$ echo $PATH rsm@lily:~/ash/bash-4.4$ As you can see, the path to 'hostname' remains in the hash in 4.4 Repeat-By: Follow example above
Re: Arbitrary command execution in shell - by design!
On 2021/10/29 12:33, Greg Wooledge wrote: On Fri, Oct 29, 2021 at 11:59:02AM -0700, L A Walsh wrote: How much lameness Chet has introduced into bash to accommodate the wrong users. This is quite unfair. Huh? It's true--look at how functions have to be stored in the environment because someone was able to hack "their own system" where they already have unrestricted shell access. If that isn't ugly or lame, what is? But it was the fault of taking actions that a hacker could do on a system where they already had shell access to corrupt their own environment. If permissions and paths were correctly set to never execute files owned by that user, I don't see how that exploit would gain root access and affect anyone other the user who was injecting the code into their own function. Asking how much lameness Chet had to introduce, says nothing about fault. Think about functions and how they look in the environment. I never thought those things were a mis-design in bash, but an abuse by people who shouldn't have access to the system they supposedly could exploit. There was nothing wrong with functions on a system where the only shell user was one's self. Giving shell access to untrusted people is a problem of a specific system's security "policy". I don't bash functions should have been hacked to try to disable malformed functions as introduced from the environment. It may be true that doing so gives a site using bash better defense from attackers, but functions were not at fault -- since for the malicious user -- they need access to the system shell to use their exploit. If you give out shell access in a stock unix/linux system, it has generally been considered you've given up a large part of your security. Maybe if your system has mandatory security features like FLASK, Windows mandatory integrity labeling, SMAC (linux security option), where getting root doesn't equal game over, then it might be possible to allow shell access "in general", but the unix/linux shell was designed for a time of trusted users on a relatively closed or private academic system where the focus was on making things easier, not needing to post guards at every port, etc. There have been other similar bugs (that weren't really bugs) involving symlinks that the hacker could "magically" place in root's path (right...), or in samba -- where using linux extensions on a linux-based file server, one could create symlinks on a system where samba "widelinks" were enabled to allow symlinks to be followed across partitions (but only on partitions where widelinks were enabled and if the user was able to use samba-extended features on a particular Share. People threw a hissy fit, but a minority of samba users (self included) didn't see it as a problem since our security policy gave shell access to users (mainly me & few others) who had "shares" on the linux-based domain server. I.e. anything the user could do with samba they could do in the server's shell which they could also log into. I use my linux server as an extension to my desktop, so full access isn't a big deal. But in Windows, it is far more rare to let users have server-shell access to the servers their users import shares from. Their security policy didn't allow for users having server access, so that a user could control the links on the server was a problem. I suggested the name for the feature 'allow user controlled symlinks' or something similar. The samba folks eventually re-enabled the feature under the name "allow-insecure-widelinks"*bleh*. Most inelegant. It's that type of inelegance that had to be inserted into bash to make bash more secure in an unsecure environment that I refer to. If someone wants to hack their own shell, so what? I'm just not going to let them write shell scripts for me.