Skip to content

fix(security): prevent shell injection from Jenkins job parameters#147

Open
lfrancke wants to merge 1 commit into
mainfrom
fix/runner-command-injection
Open

fix(security): prevent shell injection from Jenkins job parameters#147
lfrancke wants to merge 1 commit into
mainfrom
fix/runner-command-injection

Conversation

@lfrancke

Copy link
Copy Markdown
Member

Security fix (blocker)

The operator test runner spliced free-text Jenkins job parameters directly into shell command strings run via os.system() / run_command() (/bin/bash -c). Anyone able to trigger an *-it-custom test job could achieve arbitrary code execution inside a container holding REPLICATED_API_TOKEN, IONOS credentials, and the cluster kubeconfig.

Injection points closed (all shlex.quote()d)

apps/src/operator-test-runner.py:

  • TEST_SCRIPT_PARAMS — both the run-tests branch and the auto-retry branch (whitespace-split tokens were rejoined verbatim, so ;/|/backticks survived).
  • OUTPUT_FILE_USERchown.
  • GIT_BRANCH + repo name → git clone.
  • OPERATOR / OPERATOR_VERSION → SDP install command.

apps/src/modules/cluster_logging.py:

  • OpenSearch endpoint / user / password interpolated into kubectl create secret — the hand-written single quotes broke on any value containing a quote. Also the cluster id.

Verification

  • ruff check apps/ clean; both files parse.
  • Demonstrated: a parameter like foo; touch X executes under the old code and is passed as a literal argument under the new code.

Note

Values are still passed via a shell (the runner relies on tee, redirection and echo $?), so quoting is the fix; a follow-up could move secrets off the command line entirely (--from-env-file=) to also avoid process-list exposure.

Part of the review follow-ups; independent of the other PRs.

The operator test runner spliced free-text Jenkins parameters straight
into shell command strings executed via os.system() / run_command()
(which runs `/bin/bash -c`). A user able to trigger a test job could get
arbitrary code execution in a container holding REPLICATED_API_TOKEN,
IONOS credentials and the cluster kubeconfig.

Quote every externally-controlled value with shlex.quote():
- operator-test-runner.py: TEST_SCRIPT_PARAMS (both the run-tests and
  auto-retry branches), OUTPUT_FILE_USER (chown), GIT_BRANCH + repo
  (git clone), OPERATOR/OPERATOR_VERSION (SDP install).
- cluster_logging.py: the OpenSearch endpoint/user/password interpolated
  into `kubectl create secret` (single quotes there did not survive a
  value containing a quote), plus the cluster id.

Verified: a param like `foo; touch X` executes under the old code and is
passed as a literal argument under the new code.
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.

1 participant