Skip to content

[Security] Sanitize user inputs to prevent OS command injection via SSM#469

Merged
hehe7318 merged 3 commits intoaws:mainfrom
hehe7318:wip/fix-command-injection
Apr 21, 2026
Merged

[Security] Sanitize user inputs to prevent OS command injection via SSM#469
hehe7318 merged 3 commits intoaws:mainfrom
hehe7318:wip/fix-command-injection

Conversation

@hehe7318
Copy link
Copy Markdown
Contributor

@hehe7318 hehe7318 commented Apr 14, 2026

Description

Use shlex.quote to prevent OS command injection via SSM.

Affected endpoints: /sacct, /scontrol_job, /cancel_job, /get_dcv_session, /queue_status.

Changes

  • Wrap user-controlled inputs with shlex.quote before interpolating them into shell commands executed via SSM SendCommand on cluster head nodes. This is the same approach used in aws-parallelcluster CLI and is the POSIX-standard way to safely pass untrusted strings to a shell.

How Has This Been Tested?

  • Unit tests passed
  • Manually test done, I deployed PCUI stack and create a cluster. Then try command injection via SSM, it shows error code 400.

PR Quality Checklist

  • I added tests to new or existing code
  • I removed hardcoded strings and used react-i18next library (useTranslation hook and/or Trans component), see an example here
  • I made sure no sensitive info gets logged at any time in the codebase (see here) (e.g. no user info or details, no stacktraces, etc.)
  • I made sure that any GitHub issue solved by this PR is correctly linked
  • I checked that infrastructure/update_infrastructure.sh runs without any error
  • I checked that npm run build builds without any error
  • I checked that clusters are listed correctly
  • I checked that a new cluster can be created (config is produced and dry run passes)
  • I checked that login and logout work as expected

In order to increase the likelihood of your contribution being accepted, please make sure you have read both the Contributing Guidelines and the Project Guidelines

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Comment thread api/PclusterApiHandler.py Outdated
region = request.args.get("region")
body = request.json

for k, v in body.items():
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What about using shlex.quote() to escape the content of sacct_args before the interpolation into the SSM command?
I guess in that case we do not even need to specify specific patterns to reject.

I thought about it here for the JSON, but I think it could be applied to whatever command interpolation, so also for the usernmae in the other SSM command.

Copy link
Copy Markdown
Collaborator

@gmarciani gmarciani Apr 17, 2026

Choose a reason for hiding this comment

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

FYI we already use shlex for the same reasons in pcluster cli

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

…SM (P404791535)

Add shell metacharacter validation for user-controlled inputs that are
interpolated into shell commands executed via SSM SendCommand on cluster
head nodes.

Affected endpoints: /sacct, /scontrol_job, /cancel_job, /get_dcv_session,
/queue_status.

Changes:
- Add has_no_shell_metacharacters validator that rejects ;|&$`()><'"\\\n\r\0
- Apply validator to user and job_id fields in Marshmallow schemas
- Add inline validation for sacct POST JSON body keys and values
- Add 24 test cases covering legitimate inputs and injection attempts
Wrap user-controlled inputs with shlex.quote before interpolating them
into shell commands executed via SSM SendCommand on cluster head nodes.
This is the same approach used in aws-parallelcluster CLI and is the
POSIX-standard way to safely pass untrusted strings to a shell.
Verify that ssm_command safely escapes user and run_command arguments by
asserting the constructed shell string parses back into the expected
tokens
via shlex.split. A malicious input containing shell metacharacters must
round-trip as a single literal token; any regression that drops
shlex.quote
would cause the shell parser to split the input and fail the assertion.
@hehe7318 hehe7318 force-pushed the wip/fix-command-injection branch from 8d797ef to 79a3ca8 Compare April 21, 2026 16:18
@hehe7318 hehe7318 requested a review from gmarciani April 21, 2026 16:20
Comment thread api/PclusterApiHandler.py
ssm = boto3.client("ssm")

command = f"runuser -l {user} -c '{dcv_command} {session_directory}'"
inner_command = f"{dcv_command} {shlex.quote(session_directory)}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why not shlexing the dcv_command as well?

Copy link
Copy Markdown
Contributor Author

@hehe7318 hehe7318 Apr 21, 2026

Choose a reason for hiding this comment

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

See

dcv_command = "/opt/parallelcluster/scripts/pcluster_dcv_connect.sh"

It's hardcoded, not user input.

@hehe7318 hehe7318 merged commit c23f04b into aws:main Apr 21, 2026
2 checks passed
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