Skip to content

Fix command injection in contrib/sge.py qsub command#3439

Open
nileshpatil6 wants to merge 1 commit into
spotify:masterfrom
nileshpatil6:fix-sge-command-injection
Open

Fix command injection in contrib/sge.py qsub command#3439
nileshpatil6 wants to merge 1 commit into
spotify:masterfrom
nileshpatil6:fix-sge-command-injection

Conversation

@nileshpatil6

Copy link
Copy Markdown

Follows up on #3419.

The bug is in _build_qsub_command in luigi/contrib/sge.py. It builds a shell string like:

echo {cmd} | qsub -o ":{outfile}" -e ":{errfile}" -V -r y -pe {pe} {n_cpu} -N {job_name}

and runs it with subprocess.check_output(submit_cmd, shell=True).

job_name and pe come directly from SGEJobTask parameters (job_name, job_name_format, parallel_env), which are user supplied. outfile/errfile are built from shared_tmp_dir and the task id, which also come from parameters. None of these were escaped before being dropped into the shell string, so a task with something like job_name = "foo; rm -rf ~" would run that command when the job got submitted.

Fix: quote job_name, pe, outfile and errfile with shlex.quote before formatting them into the qsub command. n_cpu is left alone since it's an IntParameter.

Added a test in test/contrib/sge_test.py that builds a qsub command with a job_name containing ; touch /tmp/pwned and checks that shlex.split on the qsub portion of the command sees it as one argument, not two.

Tested with:

python -m pytest test/contrib/sge_test.py -v

test_track_job and the new test_build_qsub_command_quotes_untrusted_fields pass. test_run_job_with_dump and test_run_job fail on my machine because they hit os.fstatvfs, which doesn't exist on Windows, unrelated to this change (same failure on master before my patch).

job_name, parallel_env, outfile and errfile are all interpolated
into a shell string that gets run with shell=True. job_name and
parallel_env come straight from task parameters, so a task with a
crafted job_name or parallel_env could inject arbitrary shell
commands into the qsub call.

Quote these values with shlex.quote before formatting them into the
command string. Added a test that checks a job_name containing shell
metacharacters ends up as a single quoted argument instead of being
split by the shell.

Refs spotify#3419

Signed-off-by: nileshpatil6 <technil6436@gmail.com>
@nileshpatil6 nileshpatil6 requested review from a team and dlstadther as code owners July 4, 2026 17:27
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