Skip to content

Audit and harden all module shell scripts against command injection (follow-up from dotfiles fix) #712

Description

@blinkagent

Context

The dotfiles module recently received a fix to address insecure shell expansion and missing input validation in its run.sh script. The fix added:

  • Strict character whitelist validation on URI inputs
  • URL scheme validation (only https?://, ssh://, git@, git://)
  • Proper double-quoting of all shell variables

This same class of vulnerability — unvalidated and/or unquoted user-controllable inputs interpolated into shell scripts — exists across many other modules in the registry. These need the same treatment.

Affected Modules

High Priority (user-provided URLs/paths used without validation)

git-clone/run.sh

  • REPO_URL is passed directly to git clone with no input validation (no character whitelist, no URL format check)
  • CLONE_PATH and BRANCH_NAME are also unvalidated
  • POST_CLONE_SCRIPT is base64-decoded and executed (by design, but worth noting)

personalize/run.sh

  • $SCRIPT (from PERSONALIZE_PATH) is used unquoted in multiple places: [ ! -f $SCRIPT ], [ ! -x $SCRIPT ], and direct execution $SCRIPT
  • Word splitting and globbing possible via crafted paths

filebrowser/run.sh

  • $ROOT_DIR, ${DB_PATH}, ${LOG_PATH}, ${SERVER_BASE_PATH}, ${PORT} are used unquoted in commands
  • e.g. filebrowser config set --baseURL=${SERVER_BASE_PATH} --port=${PORT} ... --root=$ROOT_DIR
  • tee -a ${LOG_PATH} is also unquoted

code-server/run.sh

  • ${ADDITIONAL_ARGS} is expanded unquoted in the run_code_server function
  • Extension names passed to --install-extension without validation

Medium Priority (internal/credential values, but still unquoted)

jfrog-oauth/run.sh and jfrog-token/run.sh

  • ${JFROG_URL}, ${JFROG_SERVER_ID}, ${ARTIFACTORY_USERNAME} used without quoting
  • ${REGISTER_DOCKER} is expanded and executed as a bare command

vault-github/run.sh

  • ${AUTH_PATH}, ${GITHUB_EXTERNAL_AUTH_ID} used in commands without strict validation

vault-jwt/run.sh

  • ${VAULT_JWT_AUTH_PATH}, ${VAULT_JWT_ROLE} used in vault write command without validation

vault-token/run.sh

  • ${VAULT_NAMESPACE} used without validation

github-upload-public-key/run.sh

  • $CODER_EXTERNAL_AUTH_ID used unquoted in commands
  • $GITHUB_API_URL used unquoted in curl calls

Recommended Fix Pattern

Follow the pattern established in the dotfiles module fix:

  1. Input validation — For URL inputs, add a strict character whitelist regex (e.g. [^a-zA-Z0-9._/:@-]) and validate the URL scheme. For path inputs, validate against shell metacharacters.
  2. Quote all variables — Every $VAR and ${VAR} used in shell commands must be wrapped in double quotes to prevent word splitting and globbing.
  3. set -euo pipefail — Ensure all scripts start with this for fail-fast behavior (some already do, some don't).
  4. Test coverage — Verify that valid inputs still work and that payloads containing ;, &, |, $, backticks, (, ) etc. are rejected.

Example: git-clone/run.sh

Before:

REPO_URL="${REPO_URL}"
# ... no validation ...
git clone "$REPO_URL" "$CLONE_PATH"

After (following dotfiles pattern):

REPO_URL="${REPO_URL}"
if [ -n "$REPO_URL" ]; then
  if [[ "$REPO_URL" =~ [^a-zA-Z0-9._/:@-] ]]; then
    echo "ERROR: REPO_URL contains invalid characters" >&2
    exit 1
  fi
  if ! [[ "$REPO_URL" =~ ^(https?://|ssh://|git@|git://) ]]; then
    echo "ERROR: REPO_URL must be a valid repository URL" >&2
    exit 1
  fi
fi

Created on behalf of @DevelopmentCats

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions