Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
46 changes: 46 additions & 0 deletions src/cloud/azure/custom/api.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,52 @@ sub azure_list_sqlvms {
return $full_response;
}

sub azure_list_resource_metrics_set_url {
my ($self, %options) = @_;

my $url = $self->{management_endpoint};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

azure_list_resource_metrics_set_url concatenates $options{resource} directly into the request URL without encoding; untrusted resource values can manipulate the constructed HTTP path.

Details

✨ AI Reasoning
​The management API URL is constructed by appending '/' . $options{resource} into the base management endpoint string. If $options{resource} is supplied externally, it may contain unexpected characters or sequences that change the resulting HTTP request (path traversal, injection into the URL). No encoding or validation is applied before concatenation.

🔧 How do I fix it?
Use parameterized queries with placeholders, array-based command execution (no shell interpretation), or properly escaped arguments using vetted libraries. Avoid dynamic queries/commands built with user input concatenation.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

$url .= "/" . $options{resource} . "/providers/microsoft.insights/metricDefinitions";
$url .= (defined($options{force_api_version}) && $options{force_api_version} ne '') ? "?api-version=" . $options{force_api_version} : "?api-version=" . $self->{api_version};
return $url;
}

sub azure_list_resource_metrics {
my ($self, %options) = @_;

my $full_response = [];
my $full_url = $self->azure_list_resource_metrics_set_url(%options);
while (1) {
my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => '');
foreach (@{$response->{value}}) {
push @$full_response, $_;
}

last if (!defined($response->{nextLink}));
$full_url = $response->{nextLink};
}

return $full_response;
}

sub azure_list_netapp_volumes_set_url {
my ($self, %options) = @_;

my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription} . "/resourcegroups/" .

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

azure_list_netapp_volumes_set_url concatenates resource_group, account_name and pool_name directly into the URL path without encoding or validation; this may allow crafted input to manipulate the request URL.

Details

✨ AI Reasoning
​The new API helper composes an HTTP URL by concatenating resource_group, account_name and pool_name directly into the path. These values originate from options and are included without escaping/encoding. This can cause malformed requests or allow an attacker to control request paths.

🔧 How do I fix it?
Use parameterized queries with placeholders, array-based command execution (no shell interpretation), or properly escaped arguments using vetted libraries. Avoid dynamic queries/commands built with user input concatenation.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

$options{resource_group} . "/providers/Microsoft.NetApp/netAppAccounts/" . $options{account_name} .
"/capacityPools/" . $options{pool_name} . "/volumes?api-version=" . $self->{api_version};

return $url;
}

sub azure_list_netapp_volumes {
my ($self, %options) = @_;

my $full_url = $self->azure_list_netapp_volumes_set_url(%options);
my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => '');

return $response->{value};
}

sub azure_list_sqlelasticpools_set_url {
my ($self, %options) = @_;

Expand Down
38 changes: 38 additions & 0 deletions src/cloud/azure/custom/azcli.pm
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,44 @@ sub azure_get_publicip {
return $self->execute(cmd_options => $cmd_options);
}

sub azure_list_resource_metrics_set_cmd {
my ($self, %options) = @_;

return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '');

my $cmd_options = "monitor metrics list-definitions --resource '$options{resource}' --only-show-errors --output json";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

azure_list_resource_metrics_set_cmd builds a shell command by concatenating --resource and other option values into cmd_options; this allows command injection. Use safe argument passing or proper escaping.

Details

✨ AI Reasoning
​A command string is being assembled by concatenating user-controllable option values directly into a shell-invoked command. This allows arbitrary shell metacharacters or injection to be included by an attacker, leading to command injection when executed. The problematic change constructs a command line with resource, resource_group and other fields interpolated without escaping or using a safe exec-array API.

🔧 How do I fix it?
Use parameterized queries with placeholders, array-based command execution (no shell interpretation), or properly escaped arguments using vetted libraries. Avoid dynamic queries/commands built with user input concatenation.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info


return $cmd_options;
}

sub azure_list_resource_metrics {
my ($self, %options) = @_;

my $cmd_options = $self->azure_list_resource_metrics_set_cmd(%options);
my $raw_results = $self->execute(cmd_options => $cmd_options);

return $raw_results;
}

sub azure_list_netapp_volumes_set_cmd {
my ($self, %options) = @_;

return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '');

my $cmd_options = "netappfiles volume list --account-name '$options{account_name}' --pool-name '$options{pool_name}' --resource-group '$options{resource_group}'";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

azure_list_netapp_volumes_set_cmd builds a shell command by concatenating --account-name, --pool-name and --resource-group option values into cmd_options; this allows command injection. Use safe argument passing or proper escaping.

Details

✨ AI Reasoning
​A command string is being assembled by concatenating user-controllable option values directly into a shell-invoked command. This allows arbitrary shell metacharacters or injection to be included by an attacker, leading to command injection when executed. The problematic change constructs a command line with account_name, pool_name and resource_group interpolated without escaping or using a safe exec-array API.

🔧 How do I fix it?
Use parameterized queries with placeholders, array-based command execution (no shell interpretation), or properly escaped arguments using vetted libraries. Avoid dynamic queries/commands built with user input concatenation.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

$cmd_options .= " --subscription '$self->{subscription}'" if (defined($self->{subscription}) && $self->{subscription} ne '');
return $cmd_options;
}

sub azure_list_netapp_volumes_metrics {

@aikido-pr-checks aikido-pr-checks Bot May 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Method name mismatch: azcli defines azure_list_netapp_volumes_metrics, but callers use azure_list_netapp_volumes. This causes runtime failure with --custommode=azcli.

Suggested change
sub azure_list_netapp_volumes_metrics {
sub azure_list_netapp_volumes {
Details

✨ AI Reasoning
​​1) The new list-volumes mode asks the custom object for a method named azure_list_netapp_volumes.
​2) The API custom implementation provides that method, but the CLI custom implementation introduces a differently named method instead.
​3) With the CLI custom mode selected, that call cannot be resolved, so execution fails before data retrieval.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

my ($self, %options) = @_;

my $cmd_options = $self->azure_list_netapp_volumes_set_cmd(%options);
my $raw_results = $self->execute(cmd_options => $cmd_options);

return $raw_results;
}

1;

__END__
Expand Down
Loading