Skip to content

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

@blinkagent

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

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