From 1d5dc3ee8744a5f9e339bf7ae7d8c35321c6edbd Mon Sep 17 00:00:00 2001 From: necusjz Date: Tue, 3 Mar 2026 14:15:58 +1100 Subject: [PATCH 1/5] fix: command injection --- src/azure-cli-core/azure/cli/core/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index 75a421f5dfd..af8d0510eab 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -804,7 +804,7 @@ def open_page_in_browser(url): # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe # Ampersand (&) should be quoted return subprocess.Popen( - ['powershell.exe', '-NoProfile', '-Command', 'Start-Process "{}"'.format(url)]).wait() + ['powershell.exe', '-NoProfile', '-Command', 'Start-Process', url]).wait() except OSError: # WSL might be too old # FileNotFoundError introduced in Python 3 pass elif platform_name == 'darwin': From 3466a2ca48294a54133001293f077f7cf732a0b4 Mon Sep 17 00:00:00 2001 From: necusjz Date: Tue, 3 Mar 2026 14:33:40 +1100 Subject: [PATCH 2/5] Update src/azure-cli-core/azure/cli/core/util.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/azure-cli-core/azure/cli/core/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index af8d0510eab..23fd2ceac2c 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -804,7 +804,7 @@ def open_page_in_browser(url): # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe # Ampersand (&) should be quoted return subprocess.Popen( - ['powershell.exe', '-NoProfile', '-Command', 'Start-Process', url]).wait() + ['powershell.exe', '-NoProfile', '-Command', f'Start-Process "{url}"']).wait() except OSError: # WSL might be too old # FileNotFoundError introduced in Python 3 pass elif platform_name == 'darwin': From 76a7e355a33a79dabb73d156e804285c9b565914 Mon Sep 17 00:00:00 2001 From: necusjz Date: Tue, 3 Mar 2026 14:38:11 +1100 Subject: [PATCH 3/5] chore: revert changes from copilot --- src/azure-cli-core/azure/cli/core/tests/test_util.py | 2 +- src/azure-cli-core/azure/cli/core/util.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/tests/test_util.py b/src/azure-cli-core/azure/cli/core/tests/test_util.py index 28843f255b8..041936d8ac1 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_util.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_util.py @@ -157,7 +157,7 @@ def test_open_page_in_browser(self, subprocess_open_mock, webbrowser_open_mock): open_page_in_browser('http://foo') if is_wsl(): subprocess_open_mock.assert_called_once_with(['powershell.exe', '-NoProfile', - '-Command', 'Start-Process "http://foo"']) + '-Command', 'Start-Process', 'http://foo']) elif platform == 'darwin': subprocess_open_mock.assert_called_once_with(['open', 'http://foo']) else: diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index 23fd2ceac2c..af8d0510eab 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -804,7 +804,7 @@ def open_page_in_browser(url): # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe # Ampersand (&) should be quoted return subprocess.Popen( - ['powershell.exe', '-NoProfile', '-Command', f'Start-Process "{url}"']).wait() + ['powershell.exe', '-NoProfile', '-Command', 'Start-Process', url]).wait() except OSError: # WSL might be too old # FileNotFoundError introduced in Python 3 pass elif platform_name == 'darwin': From 60dd1cc33c78c30057f7b42981837ffb117e01e5 Mon Sep 17 00:00:00 2001 From: necusjz Date: Wed, 4 Mar 2026 14:22:40 +1100 Subject: [PATCH 4/5] test: better case coverage --- src/azure-cli-core/azure/cli/core/tests/test_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/tests/test_util.py b/src/azure-cli-core/azure/cli/core/tests/test_util.py index 041936d8ac1..f603776bd8d 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_util.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_util.py @@ -154,10 +154,10 @@ def test_proxy_resource_parse(self): @mock.patch('subprocess.Popen', autospec=True) def test_open_page_in_browser(self, subprocess_open_mock, webbrowser_open_mock): platform = sys.platform.lower() - open_page_in_browser('http://foo') + open_page_in_browser("http://foo") if is_wsl(): subprocess_open_mock.assert_called_once_with(['powershell.exe', '-NoProfile', - '-Command', 'Start-Process', 'http://foo']) + '-Command', 'Start-Process', '"http://foo"']) elif platform == 'darwin': subprocess_open_mock.assert_called_once_with(['open', 'http://foo']) else: From d673f119c10858030a6a2bd6ea022d0e5d1fcf16 Mon Sep 17 00:00:00 2001 From: necusjz Date: Fri, 6 Mar 2026 10:47:49 +1100 Subject: [PATCH 5/5] chore: apply comments' change --- src/azure-cli-core/azure/cli/core/tests/test_util.py | 2 +- src/azure-cli-core/azure/cli/core/util.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/tests/test_util.py b/src/azure-cli-core/azure/cli/core/tests/test_util.py index f603776bd8d..a21a1371cf8 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_util.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_util.py @@ -157,7 +157,7 @@ def test_open_page_in_browser(self, subprocess_open_mock, webbrowser_open_mock): open_page_in_browser("http://foo") if is_wsl(): subprocess_open_mock.assert_called_once_with(['powershell.exe', '-NoProfile', - '-Command', 'Start-Process', '"http://foo"']) + '-Command', "Start-Process 'http://foo'"]) elif platform == 'darwin': subprocess_open_mock.assert_called_once_with(['open', 'http://foo']) else: diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index af8d0510eab..c703a56cb37 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -803,8 +803,9 @@ def open_page_in_browser(url): try: # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe # Ampersand (&) should be quoted + safe_url = url.replace("'", "''") return subprocess.Popen( - ['powershell.exe', '-NoProfile', '-Command', 'Start-Process', url]).wait() + ['powershell.exe', '-NoProfile', '-Command', f"Start-Process '{safe_url}'"]).wait() except OSError: # WSL might be too old # FileNotFoundError introduced in Python 3 pass elif platform_name == 'darwin':