Cloud azure network virtualnetwork latency#6145
Conversation
…om/i-Vertix/centreon-plugins into cloud-azure-network-virtualnetwork
|
|
||
| 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"; |
There was a problem hiding this comment.
Command string built in azure_list_resource_metrics_set_cmd interpolates $options{resource} directly into cmd_options; this can lead to command injection when passed to execute. Use safer parameterization or escape/validate input before concatenation.
Details
✨ AI Reasoning
The new azure_list_resource_metrics_set_cmd builds a shell command string by concatenating user-provided options into cmd_options, then that string is passed to execute which runs the Azure CLI. Concatenating untrusted input into shell commands can lead to command injection if inputs (like resource) are attacker-controlled or not validated/escaped. The change introduces a new command construction site using $options{resource} directly. This harms code quality/security because it creates a new vector for injection; fixing would require parameterization or proper escaping of input before embedding in the command string.
🔧 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
| $resource_group = $1; | ||
| $resource_name = $2; | ||
| } else { | ||
| $resource = "/subscriptions/" . $self->{az_subscription_id} . "/resourceGroups/" . $resource_group . "/providers/Microsoft.Network/virtualNetworks/" . $resource_name; |
There was a problem hiding this comment.
User-controlled values ($self->{az_subscription_id}, $resource_group, $resource_name) are concatenated into a resource path string. Avoid building API paths via raw string concatenation of untrusted input; validate or normalize components before use.
Details
✨ AI Reasoning
The code constructs an Azure resource path by concatenating subscription id, resource group, and resource name into a single string. This value originates from user-supplied options (resource and possibly resource_group). Concatenating untrusted inputs into an API resource path can allow crafted values to change the resource being queried or inject unexpected path segments. This is risky because the constructed string is subsequently passed to azure_list_resource_metrics for an API call, and there is no validation, normalization, or escaping of the components before concatenation. The finding focuses on the specific string construction operation introduced in this change.
🔧 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
| my ($self, %options) = @_; | ||
| $self->SUPER::check_options(%options); | ||
|
|
||
| if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { |
There was a problem hiding this comment.
Validation allows --resource without --resource-group, but name-based path construction always uses resource_group. This can build an invalid resource ID while passing check_options.
Show fix
| if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { | |
| if (!defined($self->{option_results}->{resource}) || $self->{option_results}->{resource} eq '') { | |
| my $resource_is_id = 0; | |
| foreach my $resource (@{$self->{option_results}->{resource}}) { | |
| if ($resource =~ /^\/subscriptions\//) { | |
| $resource_is_id = 1; | |
| last; | |
| } | |
| } | |
| if (!$resource_is_id && (!defined($self->{option_results}->{resource_group}) || $self->{option_results}->{resource_group} eq '')) { | |
| $self->{output}->add_option_msg(short_msg => | |
| 'Need to specify either --resource <name> with --resource-group option or --resource <id>.'); | |
| $self->{output}->option_exit(); | |
| } | |
Details
✨ AI Reasoning
The code intends to accept either a full resource ID or a resource name paired with a group. However, the option check only verifies that a resource value exists. In the non-ID branch, it still constructs the resource path using the group value even when that value was never required. This creates an inconsistent control flow where an input explicitly described as invalid can pass validation and then produce an invalid request path.
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 $url = $self->{management_endpoint}; | ||
| $url .= "/" . $options{resource} . "/providers/microsoft.insights/metricDefinitions"; |
There was a problem hiding this comment.
Constructing URL with $options{resource} via string concatenation. Use proper encoding/validation for resource inputs before building the URL.
Details
✨ AI Reasoning
A new function constructs a management API URL by concatenating user-provided resource value directly into the path. User-supplied resource strings flow into an HTTP request URL without encoding or validation, allowing control characters or path manipulation. This can lead to unexpected requests or injection-like behaviour when upstream callers pass untrusted input. The problematic change was introduced in the new azure_list_resource_metrics_set_url implementation and is limited to the newly added code.
🔧 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
|
|
||
| next unless exists $metric_values{$metric}; | ||
|
|
||
| push @{$self->{az_metrics}}, $metric; |
There was a problem hiding this comment.
Appending to $self->{az_metrics} inside the per-resource loop causes the metric list to accumulate across resources; reset/initialize az_metrics per resource to avoid redundant, growing metric queries.
Details
✨ AI Reasoning
The code iterates over each provided resource and, for each resource, appends matching metric names into $self->{az_metrics} using 'push @{$self->{az_metrics}}, $metric'. There is no reset/initialization of $self->{az_metrics} inside the per-resource loop, so when multiple resources are processed the metrics list will accumulate values from prior resources. This makes subsequent calls (azure_get_metrics) request an ever-growing set of metrics for each resource, increasing network and processing cost as the number of resources increases. The issue is introduced by the added line that pushes into $self->{az_metrics} inside the resource loop.
🔧 How do I fix it?
Move constant work outside loops. Use StringBuilder instead of string concatenation in loops. Cache compiled regex patterns. Use hash-based lookups instead of nested loops. Batch database operations instead of N+1 queries.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
Community contributors
Description
A latency mode has been added to the plugin.
PingMeshAverageRoundtripMs and PingMeshProbesFailedPercent are monitored as metrics.
I have implemented a process where the available metrics for the resource are first queried via the /providers/microsoft.insights/metricDefinitions endpoint.
for API
https://learn.microsoft.com/en-us/rest/api/monitor/metric-definitions/list?view=rest-monitor-2023-10-01&tabs=HTTP
for CLI
https://learn.microsoft.com/en-us/cli/azure/monitor/metrics?view=azure-cli-latest#az-monitor-metrics-list-definitions
This also allows you to determine the primaryAggregationType and use it if it has not been overridden with --aggregation.
Not all metrics are always available for all regions or features. That is why this is a good dynamic solution.
Type of change
How this pull request can be tested ?
use the anonymized debug output to test it
latency.debug.txt
Checklist
Summary by Aikido
🚀 New Features
⚡ Enhancements
More info