Skip to content

Azure: subscriptions sharing a display name collapse into one; only one is scanned #10719

@ivan-necheporenko

Description

@ivan-necheporenko

Issue search

  • I have searched the existing issues and this bug has not been reported yet

Which component is affected?

Prowler CLI/SDK

Cloud Provider (if applicable)

Azure

Steps to Reproduce

  1. Use an Azure tenant that contains several subscriptions sharing the same display_name (for example, auto-generated names under certain billing account types — all subscriptions show the same name in az account list). A Service Principal with Reader assigned at a management group that covers all of them can see every subscription:
    az account list --query "[].{name:name, id:id, state:state}" -o table
    Name              State
    ----------------  -------
    <same-name>       Enabled
    <same-name>       Enabled
    <same-name>       Enabled
    <same-name>       Enabled
    
  2. Run any Azure scan, either letting Prowler auto-discover the subscriptions:
    prowler azure --sp-env-auth
    
    or passing the IDs explicitly:
    prowler azure --sp-env-auth --subscription-ids <ID1> <ID2> <ID3> <ID4>
    
  3. Observe Prowler's banner and the resulting CSV.

Expected behavior

All four subscriptions are scanned, and each one is represented in identity.subscriptions and in the output CSV (one row per finding per subscription).

Actual Result with Screenshots or Logs

Only a single subscription is scanned regardless of how many were requested. Prowler's banner line lists just one subscription:

· Azure Subscriptions: ['<same-name>: <last-subscription-id>']

The output CSV contains findings only for that last subscription; the other subscription IDs do not appear anywhere in the file.

Root cause (in prowler/providers/azure/azure_provider.py, AzureProvider.setup_identity):

if not subscription_ids:
    for subscription in subscriptions_client.subscriptions.list():
        identity.subscriptions.update(
            {subscription.display_name: subscription.subscription_id}
        )
else:
    for id in subscription_ids:
        subscription = subscriptions_client.subscriptions.get(subscription_id=id)
        identity.subscriptions.update({subscription.display_name: id})

identity.subscriptions is a dict keyed by display_name. Azure allows multiple subscriptions to share the same display_name, so each update() call overwrites the previous entry and only the last subscription survives. The dictionary is later consumed by every downstream service and by output/reporting code, so only that surviving subscription is scanned.

The argparse definition for --subscription-ids (prowler/providers/azure/lib/arguments/arguments.py) uses nargs="+" and parses the list correctly — the list arrives intact at setup_identity. The bug is purely in how the dictionary is built.

How did you install Prowler?

From brew (brew install prowler)

Environment Resource

Workstation

OS used

macOS

Prowler version

5.23.0 (also confirmed against the 5.18.3 container image — same code path is unchanged)

Python version

3.12

Pip version

Not applicable (installed via brew)

Context

Workaround until this is fixed: invoke Prowler once per subscription, passing a single --subscription-ids <ID> each time. With one ID per process no dictionary collision can occur, so every subscription is scanned independently.

Fix proposed in #10718.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugprovider/azureIssues/PRs related with the Azure providerseverity/mediumResults in some unexpected or undesired behavior.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions