Skip to content

{Packaging} Harden cross-platform launchers against CWD imports#33781

Closed
naga-nandyala wants to merge 1 commit into
Azure:devfrom
naga-nandyala:harden-cross-platform-az-launchers
Closed

{Packaging} Harden cross-platform launchers against CWD imports#33781
naga-nandyala wants to merge 1 commit into
Azure:devfrom
naga-nandyala:harden-cross-platform-az-launchers

Conversation

@naga-nandyala

@naga-nandyala naga-nandyala commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Related command

az

Description

Follow up on #33780 by hardening the remaining production Azure CLI launch paths against current-working-directory module shadowing.

python -m azure.cli prepends the current directory to sys.path, which can execute an attacker-controlled azure.py or azure package when Azure CLI is launched from an untrusted directory. This PR:

  • invokes the trusted azure/cli/__main__.py directly from the macOS and RPM launchers;
  • removes CWD from sys.path before runpy execution in the curl, Windows batch, and Windows PowerShell launchers while retaining Python 3.10 and source-layout compatibility;
  • preserves Python exit codes through the PowerShell wrapper;
  • invokes the trusted Azure CLI entry-point file for the Cognitive Services nested ACR login; and
  • adds focused hostile-CWD regression tests plus an invariant covering production launch paths.

Related security context: #21261 and #33780.

Merge prerequisite: src/azure-cli/azps.ps1 contains an embedded Authenticode signature. Because this source change invalidates the existing signature, the file must be re-signed by the Azure CLI release/signing process before merge or packaging.

Testing Guide

python3 -m unittest -v scripts/release/tests/test_launcher_security.py
python3 -m py_compile scripts/curl_install_pypi/install.py scripts/release/tests/test_launcher_security.py src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py
bash -n scripts/release/macos/templates/az_launcher.sh.in

The regression suite renders and runs the macOS and curl launchers from a temporary hostile directory, verifies arguments and exit codes, and asserts that malicious CWD modules are not executed.

Additional local validation:

  • PowerShell parser validation passed.
  • PowerShell and batch bootstrap smoke tests passed from a hostile CWD with exit-code propagation.
  • New test and Cognitive Services Python surfaces pass repository-configured pylint.
  • The legacy curl installer retains its existing pylint findings; this change adds none.

History Notes

None.


🤖 PR Validation — ️✔️ All clear

Breaking Changes Tests
️✔️ None ️✔️ 130/130

Copilot AI review requested due to automatic review settings July 24, 2026 00:49
@naga-nandyala
naga-nandyala requested review from a team as code owners July 24, 2026 00:49
@azure-client-tools-bot-prd

Copy link
Copy Markdown

Hi @naga-nandyala,
Since the current milestone time is less than 7 days, this pr will be reviewed in the next milestone.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@a0x1ab

a0x1ab commented Jul 24, 2026

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 Azure CLI “production” launcher paths against current-working-directory (CWD) module shadowing (e.g., attacker-controlled azure.py in the launch directory), by avoiding python -m azure.cli and/or removing CWD from sys.path before dispatch.

Changes:

  • Updated macOS and RPM launchers to execute the trusted azure/cli/__main__.py directly.
  • Updated Windows batch/PowerShell and curl-based dispatch to remove CWD from sys.path before runpy execution, and preserved PowerShell exit codes.
  • Added targeted regression tests to ensure launcher paths do not use unsafe -m azure.cli-style entry.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/azure-cli/azure/cli/command_modules/cognitiveservices/custom.py Switches nested ACR login invocation to the trusted azure/cli/__main__.py entry file.
src/azure-cli/azps.ps1 Removes CWD from sys.path prior to module execution and preserves exit codes; adjusts PYTHONPATH for source vs installed layouts.
src/azure-cli/az.bat Removes CWD from sys.path prior to module execution; adjusts PYTHONPATH for source vs installed layouts.
scripts/release/tests/test_launcher_security.py Adds hostile-CWD regression coverage and a launcher invariant.
scripts/release/rpm/azure-cli.spec Hardens RPM launcher by executing trusted entry file via -s and explicit script path.
scripts/release/macos/templates/az_launcher.sh.in Hardens macOS launcher by executing trusted entry file via -s and explicit script path.
scripts/curl_install_pypi/install.py Hardens curl-install dispatch by removing CWD from sys.path before runpy execution.

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

)
python_wrapper.chmod(0o755)

dispatch_template = runpy.run_path(str(CURL_INSTALLER))['AZ_DISPATCH_TEMPLATE']
Comment on lines +125 to +127
contents = launcher_path.read_text(encoding='utf-8')
self.assertNotIn('-m azure.cli', contents)
self.assertNotIn("'-m', 'azure.cli'", contents)
@wangzelin007

Copy link
Copy Markdown
Member

Hi Naga,
I think the current filter may remove a legitimate import path as well. It removes every sys.path entry that resolves to the CWD, so if the CWD happens to be the source root or an installed site-packages directory, the trusted Azure CLI path is removed too.

Could we preserve the trusted source/install path while removing the implicit CWD entries? A regression test where CWD matches a legitimate module path would help cover this case.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants