Azure / azure-cli

Azure Command-Line Interface
MIT License
4.03k stars 3.01k forks source link

az storage container generate-sas succeeds even if given an invalid connection string #29895

Open ejschoen opened 2 months ago

ejschoen commented 2 months ago

Describe the bug

Consider the case of an organization that periodically (i.e., daily) rotates storage account keys. There can be a delay between the key being rotated and the updated value being made available (i.e. in an Azure Kubernetes scenario, from the Azure key value to a Kubernetes secret that's managed by secrets-store.csi.k8s.io). During this interval, a software component may try to fetch a SAS token using the now invalid connection string. az storage container generate-sas will return a valid-looking SAS token that cannot be subsequently used. For example, azcopy will fail with an AuthorizationFailed error.

This is an issue for organizations that use az storage azcopy ... commands. While these commands don't take SAS tokens, they do take connection strings. Furthermore, they always return status 0 even if the connection string is invalid. (See #20319, which is not getting any attention, even after 3 years). An application that needs to validate a connection string using generate-sas can't determine if the SAS token generated by a (bad) connection string is a bad SAS token.

Related command

Call with a bogus ConnectionString

$ az storage container generate-sas --expiry $(date -u -d "10 minutes" "+%Y-%m-%dT%H:%MZ") -n i2kcfg --permissions rl --connection-string "DefaultEndpointsProtocol=https;AccountName=****;AccountKey=/ZeFv57zUvSMaVB5sMa+91ksxfgGx3n3giR/6l==;EndpointSuffix=core.windows.net"

Errors

Outputs a righteous looking SAS token:

"se=2024-09-11T22%3A56Z&sp=rl&sv=2022-11-02&sr=c&sig=xH/LVxnbh64jzeWnNw5O/l/%2BrwGoKPylS6C2J82gZiE%3D"

Issue script & Debug output

cli.knack.cli: Command arguments: ['storage', 'container', 'generate-sas', '--expiry', '2024-09-11T23:00Z', '-n', 'i2kcfg', '--permissions', 'rl', '--connection-string', 'DefaultEndpointsProtocol=https;AccountName=i2kstorage;AccountKey=/ZeFv57zUvSMaVB5sMa+91ksxfgGx3n3giR/6l==;EndpointSuffix=core.windows.net', '--debug']
cli.knack.cli: __init__ debug log:
Enable color in terminal.
cli.knack.cli: Event: Cli.PreExecute []
cli.knack.cli: Event: CommandParser.OnGlobalArgumentsCreate [<function CLILogging.on_global_arguments at 0x7f6cc5f7bf60>, <function OutputProducer.on_global_arguments at 0x7f6cc5f2a160>, <function CLIQuery.on_global_arguments at 0x7f6cc5d47c40>]
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableCreate []
cli.azure.cli.core: Modules found from index for 'storage': ['azure.cli.command_modules.storage', 'azext_storage_preview', 'azext_storage_blob_preview']
cli.azure.cli.core: Loading command modules:
cli.azure.cli.core: Name                  Load Time    Groups  Commands
cli.azure.cli.core: storage                   0.167        59       273
cli.azure.cli.core: Total (1)                 0.167        59       273
cli.azure.cli.core: These extensions are not installed and will be skipped: ['azext_ai_examples', 'azext_next']
cli.azure.cli.core: Loading extensions:
cli.azure.cli.core: Name                  Load Time    Groups  Commands  Directory
cli.azure.cli.core: storage-blob-preview      0.004         6        10  /home/i2kdevops/.azure/cliextensions/storage-blob-preview
cli.knack.cli: Event: CommandLoader.OnLoadCommandTable []
cli.azure.cli.core: storage-preview           0.014        17        60  /home/i2kdevops/.azure/cliextensions/storage-preview
cli.azure.cli.core: Total (2)                 0.018        23        70  
cli.azure.cli.core: Loaded 67 groups, 300 commands.
cli.azure.cli.core: Found a match in the command table.
cli.azure.cli.core: Raw command  : storage container generate-sas
cli.azure.cli.core: Command table: storage container generate-sas
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableTruncate [<function AzCliLogging.init_command_file_logging at 0x7f6cc5196ca0>]
cli.azure.cli.core.azlogging: metadata file logging enabled - writing logs to '/home/i2kdevops/.azure/commands/2024-09-11.17-50-57.storage_container_generate-sas.2548443.log'.
az_command_data_logger: command args: storage container generate-sas --expiry {} -n {} --permissions {} --connection-string {} --debug
cli.knack.cli: Event: CommandInvoker.OnPreArgumentLoad [<function register_global_subscription_argument.<locals>.add_subscription_parameter at 0x7f6cc51c3d80>]
cli.azure.cli.core.profiles._shared: Traceback (most recent call last):
  File "/opt/az/lib/python3.11/site-packages/azure/cli/core/profiles/_shared.py", line 656, in _get_attr
    op = import_module(full_mod_path)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/az/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'azext_storage_blob_preview.vendored_sdks.azure_storage_blob.v2021_12_02.blob'

cli.azure.cli.core.profiles._shared: Traceback (most recent call last):
  File "/opt/az/lib/python3.11/site-packages/azure/cli/core/profiles/_shared.py", line 656, in _get_attr
    op = import_module(full_mod_path)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/az/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'azext_storage_blob_preview.vendored_sdks.azure_storage_blob.v2021_12_02.file'

cli.knack.cli: Event: CommandInvoker.OnPostArgumentLoad []
cli.knack.cli: Event: CommandInvoker.OnPostCommandTableCreate [<function register_ids_argument.<locals>.add_ids_arguments at 0x7f6cc51eb240>, <function register_cache_arguments.<locals>.add_cache_arguments at 0x7f6cc51eb380>]
cli.knack.cli: Event: CommandInvoker.OnCommandTableLoaded []
cli.knack.cli: Event: CommandInvoker.OnPreParseArgs []
cli.knack.cli: Event: CommandInvoker.OnPostParseArgs [<function OutputProducer.handle_output_argument at 0x7f6cc5f2a200>, <function CLIQuery.handle_query_parameter at 0x7f6cc5d47ce0>, <function register_ids_argument.<locals>.parse_ids_arguments at 0x7f6cc51eb2e0>]
az_command_data_logger: extension name: storage-blob-preview
az_command_data_logger: extension version: 1.0.0b1
cli.azure.cli.core.commands: The behavior of this command has been altered by the following extension: storage-blob-preview
cli.knack.cli: Event: CommandInvoker.OnTransformResult [<function _resource_group_transform at 0x7f6cc51e8220>, <function _x509_from_base64_to_hex_transform at 0x7f6cc51e82c0>]
cli.knack.cli: Event: CommandInvoker.OnFilterResult []
"se=2024-09-11T23%3A00Z&sp=rl&sv=2021-12-02&sr=c&sig=%2BSLUBV0ApHihrQ6Zt407M1yql6Ejkg%2BFMfTgZn/aOZw%3D"
cli.knack.cli: Event: Cli.SuccessfulExecute []
cli.knack.cli: Event: Cli.PostExecute [<function AzCliLogging.deinit_cmd_metadata_logging at 0x7f6cc5196f20>]
az_command_data_logger: exit code: 0
cli.__main__: Command ran in 0.481 seconds (init: 0.118, invoke: 0.363)
telemetry.main: Begin splitting cli events and extra events, total events: 1
telemetry.client: Accumulated 0 events. Flush the clients.
telemetry.main: Finish splitting cli events and extra events, cli events: 1
telemetry.save: Save telemetry record of length 3821 in cache
telemetry.main: Begin creating telemetry upload process.
telemetry.process: Creating upload process: "/opt/az/bin/python3 /opt/az/lib/python3.11/site-packages/azure/cli/telemetry/__init__.py /home/i2kdevops/.azure"
telemetry.process: Return from creating process
telemetry.main: Finish creating telemetry upload process.
$ 

Expected behavior

Exit to shell with non-zero status.

Environment Summary

(base) i2kdevops@btc:~/i2kdevops/azure$ az --version
azure-cli                         2.63.0 *

core                              2.63.0 *
telemetry                          1.1.0

Extensions:
storage-blob-preview             1.0.0b1
storage-preview                  1.0.0b4

Dependencies:
msal                              1.30.0
azure-mgmt-resource               23.1.1

Python location '/opt/az/bin/python3'
Extensions directory '/home/i2kdevops/.azure/cliextensions'

Python (Linux) 3.11.8 (main, Jul 31 2024, 03:40:04) [GCC 12.2.0]

Additional context

No response

azure-client-tools-bot-prd[bot] commented 2 months ago

Hi @ejschoen,

2.63.0 is not the latest Azure CLI(2.64.0).

If you haven't already attempted to do so, please upgrade to the latest Azure CLI version by following https://learn.microsoft.com/en-us/cli/azure/update-azure-cli.

yonzhan commented 2 months ago

Thank you for opening this issue, we will look into it.