-
Notifications
You must be signed in to change notification settings - Fork 0
π‘οΈ Sentinel: [HIGH] Fix shell injection and unquoted variables #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| ## 2025-05-18 - Shell Script Injection Risks via Unquoted Variables | ||
| **Vulnerability:** Unquoted variables in `entrypoint.sh` allowed argument splitting (passwords with spaces) and glob expansion (passwords with wildcards matching filenames). | ||
| **Learning:** Shell scripts are vulnerable to implicit expansion. `password="secret *"` expanded to filenames if unquoted, potentially exposing file existence or leaking data if passed to a command that prints arguments. | ||
| **Prevention:** Always quote variables (`"$VAR"`). Use `read -r` to disable backslash interpretation. Use `printf " %s" "$VAR"` to avoid format string injection. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,21 +25,21 @@ set -e | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONFIG=/var/lib/softether/vpn_server.config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ ! -f $CONFIG ] || [ ! -s $CONFIG ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ ! -f "$CONFIG" ] || [ ! -s "$CONFIG" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Generate a random PSK if not provided | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : ${PSK:=$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | fold -w 20 | head -n 1)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '# ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '=%.0s' {1..24} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $USERS ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$USERS" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo '# <use the password specified at -e USERS>' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : ${USERNAME:=user$(cat /dev/urandom | tr -dc '0-9' | fold -w 4 | head -n 1)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo \# ${USERNAME} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $PASSWORD ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$PASSWORD" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo '# <use the password specified at -e PASSWORD>' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PASSWORD=$(cat /dev/urandom | tr -dc '0-9' | fold -w 20 | head -n 1 | sed 's/.\{4\}/&./g;s/.$//;') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -130,23 +130,23 @@ if [ ! -f $CONFIG ] || [ ! -s $CONFIG ]; then | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # add user | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adduser() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf " $1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf " %s" "$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_hub UserCreate "$1" /GROUP:none /REALNAME:none /NOTE:none | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_hub UserPasswordSet "$1" /PASSWORD:"$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '# Creating user(s):' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $USERS ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=';' read -ra USER; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$USERS" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=';' read -r -a USER; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i in "${USER[@]}"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IFS=':' read username password <<<"$i" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IFS=':' read -r username password <<<"$i" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # echo "Creating user: ${username}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adduser $username $password | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adduser "$username" "$password" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done <<<"$USERS" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adduser $USERNAME $PASSWORD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| adduser "$USERNAME" "$PASSWORD" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -155,15 +155,15 @@ if [ ! -f $CONFIG ] || [ ! -s $CONFIG ]; then | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export PASSWORD='**' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # handle VPNCMD_* commands right before setting admin passwords | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $VPNCMD_SERVER ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=";" read -ra CMD; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_server $CMD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$VPNCMD_SERVER" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=";" read -r -a CMD; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_server "$CMD" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done <<<"$VPNCMD_SERVER" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $VPNCMD_HUB ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=";" read -ra CMD; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_hub $CMD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$VPNCMD_HUB" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while IFS=";" read -r -a CMD; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpncmd_hub "$CMD" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done <<<"$VPNCMD_HUB" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+165
to
167
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same issue as with
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+158
to
168
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug:
Compare with the Proposed fix if [[ "$VPNCMD_SERVER" ]]; then
while IFS=";" read -r -a CMD; do
- vpncmd_server "$CMD"
+ for c in "${CMD[@]}"; do
+ vpncmd_server "$c"
+ done
done <<<"$VPNCMD_SERVER"
fi
if [[ "$VPNCMD_HUB" ]]; then
while IFS=";" read -r -a CMD; do
- vpncmd_hub "$CMD"
+ for c in "${CMD[@]}"; do
+ vpncmd_hub "$c"
+ done
done <<<"$VPNCMD_HUB"
fiπ Committable suggestion
Suggested change
π§° Toolsπͺ Shellcheck (0.11.0)[warning] 160-160: Expanding an array without an index only gives the first element. (SC2128) [warning] 166-166: Expanding an array without an index only gives the first element. (SC2128) π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix for processing
VPNCMD_SERVERcommands is incorrect and introduces a regression.CMDis an array created byread -a. In bash,"$CMD"only expands to the first element of the array ("${CMD[0]}")."$CMD", the shell passes the entire command string (including arguments) as a single argument to thevpncmd_serverfunction. Sincevpncmdexpects the command and its arguments as separate parameters, this will cause commands with arguments to fail.read -acommand withIFS=";"splits the entire input string into the array. Thewhileloop only executes once becausereadconsumes the whole line. Since only the first element of the array is used, all subsequent commands in the semicolon-separated list are ignored.This breaks the custom configuration functionality and can lead to a failure to apply important security settings.