Skip to content

Fix OS command injection vulnerability in RDBMS#33349

Open
nehrao1 wants to merge 1 commit into
Azure:devfrom
nehrao1:fixRDBMS
Open

Fix OS command injection vulnerability in RDBMS#33349
nehrao1 wants to merge 1 commit into
Azure:devfrom
nehrao1:fixRDBMS

Conversation

@nehrao1
Copy link
Copy Markdown
Member

@nehrao1 nehrao1 commented May 11, 2026

This commit addresses ICM 31000000598917 / MSRC Case 115614 by:

  • Refactoring run_subprocess() to accept list arguments instead of interpolated strings, preventing shell metacharacters from being interpreted as command separators
  • Adding validate_git_ref() function to validate and reject shell metacharacters in branch and action names
  • Adding stdin_file parameter to replace shell redirection (< file) patterns
  • Converting all call sites (4) from string format to list format:
    • register_credential_secrets(): gh secret set with stdin file
    • register_connection_secrets(): gh secret set with -b parameter
    • github_actions_run(): gh workflow run with --ref parameter
    • gitcli_check_and_login(): gh auth login command
  • Adding comprehensive unit tests covering:
    • Valid git reference validation
    • Dangerous shell metacharacter rejection
    • List vs string argument handling
    • stdin_file parameter handling
    • Error handling and cleanup

This is a Defense in Depth fix (no trust boundary crossing). The --branch and --repository parameters are supplied by the same user who has shell access. The fix improves code hygiene by eliminating unnecessary use of shell string interpolation.

Fixes: ICM 31000000598917

Related command

Description

Testing Guide

History Notes

[Component Name 1] BREAKING CHANGE: az command a: Make some customer-facing breaking change
[Component Name 2] az command b: Add some customer-facing feature


This checklist is used to make sure that common guidelines for a pull request are followed.

…y flow

This commit addresses ICM 31000000598917 / MSRC Case 115614 by:

- Refactoring run_subprocess() to accept list arguments instead of interpolated
  strings, preventing shell metacharacters from being interpreted as command
  separators
- Adding validate_git_ref() function to validate and reject shell
  metacharacters in branch and action names
- Adding stdin_file parameter to replace shell redirection (< file) patterns
- Converting all call sites (4) from string format to list format:
  * register_credential_secrets(): gh secret set with stdin file
  * register_connection_secrets(): gh secret set with -b parameter
  * github_actions_run(): gh workflow run with --ref parameter
  * gitcli_check_and_login(): gh auth login command
- Adding comprehensive unit tests covering:
  * Valid git reference validation
  * Dangerous shell metacharacter rejection
  * List vs string argument handling
  * stdin_file parameter handling
  * Error handling and cleanup

This is a Defense in Depth fix (no trust boundary crossing). The --branch
and --repository parameters are supplied by the same user who has shell
access. The fix improves code hygiene by eliminating unnecessary use of
shell string interpolation.

Fixes: ICM 31000000598917
Copilot AI review requested due to automatic review settings May 11, 2026 07:28
@github-actions
Copy link
Copy Markdown

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented May 11, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the RDBMS flexible-server “deploy” flow against OS command injection by eliminating shell-style string commands and adding validation for user-provided git refs/workflow identifiers.

Changes:

  • Refactors run_subprocess to require list-based args and adds stdin_file support to replace shell redirection patterns.
  • Adds validate_git_ref and applies it to GitHub Actions workflow invocation inputs.
  • Adds unit tests covering git ref validation and run_subprocess behavior (list args, stdin file, error handling).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/azure-cli/azure/cli/command_modules/rdbms/_flexible_server_util.py Adds validate_git_ref, refactors run_subprocess to list args + stdin_file, and updates gh secret set call sites accordingly.
src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_common.py Validates workflow/branch inputs and converts gh invocations to list-based subprocess args.
src/azure-cli/azure/cli/command_modules/rdbms/tests/latest/test_command_injection_fixes.py Adds unit tests for validation and subprocess invocation changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +53 to +56
# Pattern to detect shell metacharacters and command injection attempts
if re.search(r'[;&$`|<>"\'\\]|\n', git_ref):
raise InvalidArgumentValueError(
'Git reference contains invalid characters. Allowed: alphanumeric, -, _, ., /')
Comment on lines +342 to +352
if stdout_show:
process = subprocess.Popen(args, stdin=stdin_handle)
else:
process = subprocess.Popen(args, stdin=stdin_handle,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait()

if process.returncode:
if not stdout_show:
stderr_output = process.stderr.read().strip().decode('UTF-8')
logger.warning(stderr_output)
Comment on lines +345 to +353
process = subprocess.Popen(args, stdin=stdin_handle,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait()

if process.returncode:
if not stdout_show:
stderr_output = process.stderr.read().strip().decode('UTF-8')
logger.warning(stderr_output)
raise CLIError('Command failed with exit code {}'.format(process.returncode))
# --------------------------------------------------------------------------------------------
"""Unit tests for command injection vulnerability fixes in RDBMS flexible-server deploy flow."""

import os
Comment on lines +212 to +215


if __name__ == '__main__':
unittest.main()
@yonzhan yonzhan assigned calvinhzy and unassigned evelyn-ys May 11, 2026
@yonzhan yonzhan added this to the Backlog milestone May 11, 2026
@necusjz
Copy link
Copy Markdown
Member

necusjz commented May 12, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 12, 2026

🔄AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.13
️✔️acs
️✔️latest
️✔️3.12
️✔️3.13
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.13
️✔️ams
️✔️latest
️✔️3.12
️✔️3.13
️✔️apim
️✔️latest
️✔️3.12
️✔️3.13
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.13
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️aro
️✔️latest
️✔️3.12
️✔️3.13
🔄backup
🔄latest
🔄3.12
🔄3.13
️✔️batch
️✔️latest
️✔️3.12
️✔️3.13
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.13
️✔️billing
️✔️latest
️✔️3.12
️✔️3.13
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.13
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.13
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.13
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.13
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.13
️✔️config
️✔️latest
️✔️3.12
️✔️3.13
️✔️configure
️✔️latest
️✔️3.12
️✔️3.13
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.13
️✔️container
️✔️latest
️✔️3.12
️✔️3.13
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.13
️✔️core
️✔️latest
️✔️3.12
️✔️3.13
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.13
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.13
️✔️dls
️✔️latest
️✔️3.12
️✔️3.13
️✔️dms
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.13
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.13
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.13
️✔️find
️✔️latest
️✔️3.12
️✔️3.13
🔄hdinsight
🔄latest
🔄3.12
🔄3.13
️✔️identity
️✔️latest
️✔️3.12
️✔️3.13
️✔️iot
️✔️latest
️✔️3.12
️✔️3.13
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.13
️✔️lab
️✔️latest
️✔️3.12
️✔️3.13
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.13
️✔️maps
️✔️latest
️✔️3.12
️✔️3.13
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.13
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.13
🔄mysql
🔄latest
🔄3.12
🔄3.13
🔄netappfiles
🔄latest
🔄3.12
🔄3.13
️✔️network
️✔️latest
️✔️3.12
️✔️3.13
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.13
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.13
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.13
️✔️profile
️✔️latest
️✔️3.12
️✔️3.13
🔄rdbms
🔄latest
🔄3.12
🔄3.13
️✔️redis
️✔️latest
️✔️3.12
️✔️3.13
🔄relay
🔄latest
🔄3.12
🔄3.13
️✔️resource
️✔️latest
️✔️3.12
️✔️3.13
️✔️role
️✔️latest
️✔️3.12
️✔️3.13
️✔️search
️✔️latest
️✔️3.12
️✔️3.13
️✔️security
️✔️latest
️✔️3.12
️✔️3.13
🔄servicebus
🔄latest
🔄3.12
🔄3.13
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.13
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.13
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.13
️✔️sql
️✔️latest
️✔️3.12
️✔️3.13
🔄sqlvm
🔄latest
🔄3.12
🔄3.13
️✔️storage
️✔️latest
️✔️3.12
️✔️3.13
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.13
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.13
️✔️util
️✔️latest
️✔️3.12
️✔️3.13
️✔️vm
️✔️latest
️✔️3.12
️✔️3.13

@azure-client-tools-bot-prd
Copy link
Copy Markdown

️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

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

Labels

Auto-Assign Auto assign by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants