Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/image-copy/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

1.0.4
++++++
* Mask the value of the `--sas-token` parameter when displaying it in the terminal

1.0.3
++++++
* Fix the issue for sasTokenParsing, removing python related warnings from the sasToken(cmd_output was unfiltered)
Expand Down
16 changes: 13 additions & 3 deletions src/image-copy/azext_imagecopy/cli_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
def run_cli_command(cmd, return_as_json=False):
try:
cmd_output = check_output(cmd, stderr=STDOUT, universal_newlines=True)
logger.debug('command: %s ended with output: %s', cmd, cmd_output)
logger.debug('command: %s ended with output: %s', _mask_output_token(cmd), cmd_output)

if return_as_json:
if cmd_output:
Expand All @@ -40,15 +40,25 @@ def run_cli_command(cmd, return_as_json=False):
raise CLIError("Command returned an unexpected empty string.")
return cmd_output
except CalledProcessError as ex:
logger.error('command failed: %s', cmd)
logger.error('command failed: %s', _mask_output_token(cmd))
logger.error('output: %s', ex.output)
raise ex
except Exception as ex:
logger.error('command ended with an error: %s', cmd)
logger.error('command ended with an error: %s', _mask_output_token(cmd))
logger.error('args: %s', ex.args)
raise ex


def _mask_output_token(cmd):
output = cmd[:]
token_param_name = "--sas-token"
if token_param_name in output:
idx = output.index(token_param_name)
output[idx + 1] = "******"
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

This function has a potential IndexError bug. If --sas-token appears as the last element in the cmd list, accessing output[idx + 1] will raise an IndexError. Add a check to ensure idx + 1 is within bounds before attempting to mask the token value.

Suggested change
output[idx + 1] = "******"
if idx + 1 < len(output):
output[idx + 1] = "******"

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +57
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

The index() method only finds the first occurrence of --sas-token. If the parameter appears multiple times in the command (though unlikely), only the first occurrence will be masked. Consider using a loop or list comprehension to mask all occurrences for more robust security.

Suggested change
if token_param_name in output:
idx = output.index(token_param_name)
output[idx + 1] = "******"
for i, arg in enumerate(output):
if arg == token_param_name and i + 1 < len(output):
output[i + 1] = "******"

Copilot uses AI. Check for mistakes.

return output
Comment on lines +52 to +59
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

The new _mask_output_token function lacks unit test coverage. Given that this is a security-related function responsible for masking sensitive SAS tokens in logs, it should have unit tests to verify correct behavior including edge cases like when --sas-token is at the end of the list, when it's missing, or when it appears multiple times.

Copilot uses AI. Check for mistakes.


def prepare_cli_command(cmd, output_as_json=True, tags=None, subscription=None, only_show_errors=None):
full_cmd = [sys.executable, '-m', 'azure.cli'] + cmd

Expand Down
2 changes: 1 addition & 1 deletion src/image-copy/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from codecs import open
from setuptools import find_packages, setup

VERSION = "1.0.3"
VERSION = "1.0.4"

CLASSIFIERS = [
'Development Status :: 4 - Beta',
Expand Down
Loading