Skip to content

Conversation

@bluPhy
Copy link
Owner

@bluPhy bluPhy commented Jan 27, 2026

πŸ›‘οΈ Sentinel: [MEDIUM] Harden entrypoint.sh against shell injection

🚨 Severity: MEDIUM
πŸ’‘ Vulnerability: Unquoted variable expansion in command processing loops allowed shell globbing (wildcard expansion), potentially leading to unintended file processing or execution if input contained characters like *.
🎯 Impact: Could be exploited to reference unexpected files or cause denial of service via malformed environment variables.
πŸ”§ Fix: Hardened entrypoint.sh by:

  • Quoting variables ($CONFIG, $username, $password) to prevent word splitting.
  • Using read -r to prevent backslash interpretation.
  • Using set -f (noglob) around command execution loops to prevent wildcard expansion while allowing argument splitting.
  • Fixed broken paths in gencert.sh pointing to /usr/bin instead of /usr/local/bin.
    βœ… Verification: Verified script syntax with bash -n.

PR created automatically by Jules for task 6480463339127224038 started by @bluPhy

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced input validation and argument handling in shell scripts to prevent unintended expansions and word-splitting issues.
    • Updated system binary paths for compatibility with installation location changes.
  • Documentation

    • Added security documentation covering shell script expansion handling best practices.

✏️ Tip: You can customize this high-level summary in your review settings.

- Hardened `copyables/entrypoint.sh` by quoting variables and using `read -r`.
- Used `set -f` to prevent globbing during command argument splitting.
- Fixed broken binary paths in `copyables/gencert.sh`.
- Created `.jules/sentinel.md` with security learnings.

Co-authored-by: bluPhy <11618798+bluPhy@users.noreply.github.com>
@google-labs-jules
Copy link

πŸ‘‹ Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a πŸ‘€ emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist
Copy link

Summary of Changes

Hello @bluPhy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the security of the Sentinel system by addressing a medium-severity shell injection vulnerability within entrypoint.sh. The changes involve implementing safer shell scripting practices, such as proper variable quoting, preventing backslash interpretation in input, and disabling globbing during command execution. Additionally, it corrects erroneous binary paths in gencert.sh and provides comprehensive documentation on the identified vulnerability and its mitigation.

Highlights

  • Shell Injection Hardening: Implemented robust measures in entrypoint.sh to prevent shell injection vulnerabilities arising from unquoted variable expansion and globbing.
  • Variable Quoting: Ensured critical variables like $CONFIG, $username, and $password are properly quoted to prevent unintended word splitting and path issues.
  • Safe Input Reading: Utilized read -r in entrypoint.sh to process user input safely, preventing backslash interpretation that could lead to unexpected behavior.
  • Globbing Prevention: Applied set -f (noglob) around command execution loops in entrypoint.sh to temporarily disable wildcard expansion, mitigating potential exploits via malformed environment variables.
  • Path Correction: Fixed incorrect hardcoded binary paths in gencert.sh, updating references from /usr/bin to /usr/local/bin for vpnserver and vpncmd.
  • Vulnerability Documentation: Added a new markdown file (.jules/sentinel.md) detailing the shell script injection vulnerability, its learning, and effective prevention strategies.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with πŸ‘ and πŸ‘Ž on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@coderabbitai
Copy link

coderabbitai bot commented Jan 27, 2026

Walkthrough

Security hardening improvements applied to shell scripts to prevent argument splitting and glob expansion vulnerabilities. Documentation added explaining the shell variable expansion vulnerability. Binary paths updated from /usr/bin to /usr/local/bin in startup and command invocations.

Changes

Cohort / File(s) Summary
Security Advisory
\.jules/sentinel\.md
New documentation file explaining unquoted variable expansion vulnerability in shell scripts, including vulnerability details, learning points, and prevention guidance using set -f and array-based practices.
Entrypoint Script Hardening
copyables/entrypoint\.sh
Enhanced argument validation with quoted variables, improved user-line parsing with -r flag, safer adduser invocations with quoted arguments, and globbing disabled via set -f around VPNCMD command processing blocks.
Binary Path Updates
copyables/gencert\.sh
Updated vpnserver and vpncmd binary paths from /usr/bin to /usr/local/bin in startup and certificate command invocations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Unquoted vars once caused dismay,
But quotes and set -f save the day!
With globbing tamed and arguments blessed,
Our scripts now shine in safer nest! ✨

πŸš₯ Pre-merge checks | βœ… 3
βœ… Passed checks (3 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly summarizes the main change: hardening entrypoint.sh against shell injection vulnerabilities, which aligns with the core fix throughout the changeset.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sentinel-harden-entrypoint-6480463339127224038

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively hardens the entrypoint.sh script against shell injection vulnerabilities by quoting variables and disabling globbing during command execution. The path corrections in gencert.sh are also accurate. I've identified a critical bug in the command processing loops for VPNCMD_SERVER and VPNCMD_HUB, where only the first of multiple semicolon-separated commands would be executed. My review includes suggestions to fix this by properly iterating over all commands.

Comment on lines +159 to +163
set -f
while IFS=";" read -ra CMD; do
vpncmd_server $CMD
done <<<"$VPNCMD_SERVER"
set +f

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

While adding set -f/set +f is a good security measure, the loop it wraps contains a critical bug. It will only execute the first of multiple semicolon-separated commands provided in $VPNCMD_SERVER. This is because read -ra CMD correctly creates an array of commands, but vpncmd_server $CMD (on the next line) only expands to the first element of that array.

To fix this and ensure all commands are executed, you need to iterate over the array, similar to how the USERS variable is processed earlier in the script.

Suggested change
set -f
while IFS=";" read -ra CMD; do
vpncmd_server $CMD
done <<<"$VPNCMD_SERVER"
set +f
set -f
while IFS=";" read -ra CMDS; do
for cmd in "${CMDS[@]}"; do
vpncmd_server $cmd
done
done <<<"$VPNCMD_SERVER"
set +f

Comment on lines +167 to +171
set -f
while IFS=";" read -ra CMD; do
vpncmd_hub $CMD
done <<<"$VPNCMD_HUB"
set +f

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Similar to the VPNCMD_SERVER loop, this loop for VPNCMD_HUB is also bugged and will only execute the first of multiple semicolon-separated commands. The read -ra CMD populates an array, but vpncmd_hub $CMD only uses the first element.

To ensure all commands from $VPNCMD_HUB are processed, you must iterate over all elements of the array.

Suggested change
set -f
while IFS=";" read -ra CMD; do
vpncmd_hub $CMD
done <<<"$VPNCMD_HUB"
set +f
set -f
while IFS=";" read -ra CMDS; do
for cmd in "${CMDS[@]}"; do
vpncmd_hub $cmd
done
done <<<"$VPNCMD_HUB"
set +f

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
copyables/entrypoint.sh (1)

149-149: Inconsistent quoting: $USERNAME and $PASSWORD are unquoted.

Line 145 correctly quotes "$username" and "$password", but this line leaves $USERNAME and $PASSWORD unquoted. For consistency and safety, these should also be quoted.

Proposed fix
-    adduser $USERNAME $PASSWORD
+    adduser "$USERNAME" "$PASSWORD"
πŸ€– Fix all issues with AI agents
In @.jules/sentinel.md:
- Line 1: The header line "## 2025-02-18 - Shell Script Injection via Globbing"
has an incorrect past date; update that date in the header to the correct
current date (e.g., "2026-01-27" or the intended publication date) so the
entry's timestamp is accurate, by editing the header string in
.jules/sentinel.md.

In `@copyables/entrypoint.sh`:
- Around line 167-171: The loop is erroneously expanding the CMD array with
unquoted word-splitting (vpncmd_hub $CMD) which loses elements; change the call
to use the array expansion vpncmd_hub "${CMD[@]}" so each read -ra CMD element
is passed as a separate argument to vpncmd_hub (leave the IFS=';' read -ra CMD
logic and set -f usage intact).
- Around line 159-163: The loop uses read -ra CMD to populate an array but then
calls vpncmd_server with "$CMD", which only expands the first element; change
the call to use the full array expansion ${CMD[*]} so all elements are passed as
separate words after IFS-based splitting (keep the surrounding set -f/set +f and
the read -ra CMD loop intact); locate the loop around the read -ra CMD and
replace the single-element expansion referenced by "$CMD" with the full
expansion ${CMD[*]} when invoking vpncmd_server.

In `@copyables/gencert.sh`:
- Line 4: The shell redirection in the command "/usr/local/bin/vpnserver start
2>&1 >/dev/null" is reversed so stderr is still printed; update the redirect to
silence both streams by reversing the order (e.g., ">/dev/null 2>&1") or using
the equivalent shorthand "&>/dev/null" on the line that runs
/usr/local/bin/vpnserver start. Ensure the changed redirection replaces the
existing one exactly where that command appears.
- Line 10: The shell command line invoking /usr/local/bin/vpncmd currently
redirects stderr before stdout ("2>&1 >/dev/null"), which leaves stderr attached
to the original stdout; swap the redirections so stdout is redirected to
/dev/null first and then stderr is redirected to the same place (or use a single
shell operator like &>/dev/null) to silence both; update the line containing
"/usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes
/PORTS:1194" accordingly.
🧹 Nitpick comments (1)
copyables/entrypoint.sh (1)

62-62: Pre-existing: incorrect redirect order.

Same issue as in gencert.sh - the redirect 2>&1 >/dev/null doesn't silence stderr. Consider fixing for consistency.

Proposed fix
-  /usr/local/bin/vpnserver start 2>&1 >/dev/null
+  /usr/local/bin/vpnserver start >/dev/null 2>&1

Similar fixes needed on lines 68, 112, and 182.

@@ -0,0 +1,5 @@
## 2025-02-18 - Shell Script Injection via Globbing
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Date appears incorrect.

The date 2025-02-18 is in the past relative to the current date (January 2026). Should this be 2026-01-27 or another date?

πŸ€– Prompt for AI Agents
In @.jules/sentinel.md at line 1, The header line "## 2025-02-18 - Shell Script
Injection via Globbing" has an incorrect past date; update that date in the
header to the correct current date (e.g., "2026-01-27" or the intended
publication date) so the entry's timestamp is accurate, by editing the header
string in .jules/sentinel.md.

Comment on lines +159 to +163
set -f
while IFS=";" read -ra CMD; do
vpncmd_server $CMD
done <<<"$VPNCMD_SERVER"
set +f
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Array expansion bug: only the first element is used.

read -ra CMD reads into an array, but $CMD without an index expands to only the first element (${CMD[0]}). This means multi-word commands will be truncated.

To preserve argument splitting (the intent behind set -f) while using the full array, use ${CMD[*]} which expands to all elements separated by the first character of IFS, then word-splits:

Proposed fix
   set -f
   while IFS=";" read -ra CMD; do
-    vpncmd_server $CMD
+    vpncmd_server ${CMD[*]}
   done <<<"$VPNCMD_SERVER"
   set +f
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set -f
while IFS=";" read -ra CMD; do
vpncmd_server $CMD
done <<<"$VPNCMD_SERVER"
set +f
set -f
while IFS=";" read -ra CMD; do
vpncmd_server ${CMD[*]}
done <<<"$VPNCMD_SERVER"
set +f
🧰 Tools
πŸͺ› Shellcheck (0.11.0)

[warning] 161-161: Expanding an array without an index only gives the first element.

(SC2128)

πŸ€– Prompt for AI Agents
In `@copyables/entrypoint.sh` around lines 159 - 163, The loop uses read -ra CMD
to populate an array but then calls vpncmd_server with "$CMD", which only
expands the first element; change the call to use the full array expansion
${CMD[*]} so all elements are passed as separate words after IFS-based splitting
(keep the surrounding set -f/set +f and the read -ra CMD loop intact); locate
the loop around the read -ra CMD and replace the single-element expansion
referenced by "$CMD" with the full expansion ${CMD[*]} when invoking
vpncmd_server.

Comment on lines +167 to +171
set -f
while IFS=";" read -ra CMD; do
vpncmd_hub $CMD
done <<<"$VPNCMD_HUB"
set +f
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same array expansion bug.

Proposed fix
   set -f
   while IFS=";" read -ra CMD; do
-    vpncmd_hub $CMD
+    vpncmd_hub ${CMD[*]}
   done <<<"$VPNCMD_HUB"
   set +f
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set -f
while IFS=";" read -ra CMD; do
vpncmd_hub $CMD
done <<<"$VPNCMD_HUB"
set +f
set -f
while IFS=";" read -ra CMD; do
vpncmd_hub ${CMD[*]}
done <<<"$VPNCMD_HUB"
set +f
🧰 Tools
πŸͺ› Shellcheck (0.11.0)

[warning] 169-169: Expanding an array without an index only gives the first element.

(SC2128)

πŸ€– Prompt for AI Agents
In `@copyables/entrypoint.sh` around lines 167 - 171, The loop is erroneously
expanding the CMD array with unquoted word-splitting (vpncmd_hub $CMD) which
loses elements; change the call to use the array expansion vpncmd_hub
"${CMD[@]}" so each read -ra CMD element is passed as a separate argument to
vpncmd_hub (leave the IFS=';' read -ra CMD logic and set -f usage intact).

set -e

/usr/bin/vpnserver start 2>&1 >/dev/null
/usr/local/bin/vpnserver start 2>&1 >/dev/null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Incorrect redirect order: stderr not silenced.

The redirect 2>&1 >/dev/null first redirects stderr to stdout (terminal), then redirects stdout to /dev/null. This means stderr still goes to the terminal. To silence both streams, the order should be reversed.

Proposed fix
-/usr/local/bin/vpnserver start 2>&1 >/dev/null
+/usr/local/bin/vpnserver start >/dev/null 2>&1
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/usr/local/bin/vpnserver start 2>&1 >/dev/null
/usr/local/bin/vpnserver start >/dev/null 2>&1
🧰 Tools
πŸͺ› Shellcheck (0.11.0)

[warning] 4-4: To redirect stdout+stderr, 2>&1 must be last (or use '{ cmd > file; } 2>&1' to clarify).

(SC2069)

πŸ€– Prompt for AI Agents
In `@copyables/gencert.sh` at line 4, The shell redirection in the command
"/usr/local/bin/vpnserver start 2>&1 >/dev/null" is reversed so stderr is still
printed; update the redirect to silence both streams by reversing the order
(e.g., ">/dev/null 2>&1") or using the equivalent shorthand "&>/dev/null" on the
line that runs /usr/local/bin/vpnserver start. Ensure the changed redirection
replaces the existing one exactly where that command appears.

while :; do
set +e
/usr/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 2>&1 >/dev/null
/usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 2>&1 >/dev/null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Same redirect order issue.

Proposed fix
-    /usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 2>&1 >/dev/null
+    /usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 >/dev/null 2>&1
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 2>&1 >/dev/null
/usr/local/bin/vpncmd localhost /SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194 >/dev/null 2>&1
🧰 Tools
πŸͺ› Shellcheck (0.11.0)

[warning] 10-10: To redirect stdout+stderr, 2>&1 must be last (or use '{ cmd > file; } 2>&1' to clarify).

(SC2069)

πŸ€– Prompt for AI Agents
In `@copyables/gencert.sh` at line 10, The shell command line invoking
/usr/local/bin/vpncmd currently redirects stderr before stdout ("2>&1
>/dev/null"), which leaves stderr attached to the original stdout; swap the
redirections so stdout is redirected to /dev/null first and then stderr is
redirected to the same place (or use a single shell operator like &>/dev/null)
to silence both; update the line containing "/usr/local/bin/vpncmd localhost
/SERVER /CSV /CMD OpenVpnEnable yes /PORTS:1194" accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants