Skip to content

new plugin for Waystream Network devices#5956

Open
rmorandell-pgum wants to merge 11 commits intocentreon:developfrom
i-Vertix:waystream
Open

new plugin for Waystream Network devices#5956
rmorandell-pgum wants to merge 11 commits intocentreon:developfrom
i-Vertix:waystream

Conversation

@rmorandell-pgum
Copy link
Copy Markdown
Contributor

@rmorandell-pgum rmorandell-pgum commented Jan 23, 2026

Community contributors

Description

Modes Available:

  • arp
  • cpu
  • cpu-detailed
  • hardware
  • interfaces
  • list-interfaces
  • list-sfp-ports
  • memory
  • ntp
  • sfp-port
  • tcpcon
  • udpcon
  • uptime

Type of change

  • Patch fixing an issue (non-breaking change)
  • New functionality (non-breaking change)
  • Functionality enhancement or optimization (non-breaking change)
  • Breaking change (patch or feature) that might cause side effects breaking part of the Software

How this pull request can be tested ?

snmpwalk for MS4000 and MS7000
snmpwalks.zip

MIB file
waystream-enterprise.zip

Checklist

  • I have followed the coding style guidelines provided by Centreon
  • I have commented my code, especially hard-to-understand areas of the PR.
  • I have rebased my development branch on the base branch (develop).
  • I have provide data or shown output displaying the result of this code in the plugin area concerned.

Centreon team (internal PR)

Description

PLEASE MAKE SURE THAT THE BRANCH PR INCLUDES JIRA TICKET ID

Please include a short resume of the changes and what is the purpose of this pull request.
Any relevant information should be added to help reviewers to understand what are the stakes
of the pull request.

Fixes # (issue)
If you are fixing a github Issue already existing, mention it here.
If you are fixing one or more JIRA ticket, mention it here too.

Type of change

  • Patch fixing an issue (non-breaking change)
  • New functionality (non-breaking change)
  • Functionality enhancement or optimization (non-breaking change)
  • Breaking change (patch or feature) that might cause side effects breaking part of the Software

How this pull request can be tested ?

Please describe the procedure to verify that the goal of the PR is matched.
Provide clear instructions so that it can be correctly tested.
Mention the automated tests included in this FOR (what they test like mode/option combinations).

Checklist

  • I have followed the coding style guidelines provided by Centreon
  • I have commented my code, especially hard-to-understand areas of the PR.
  • I have rebased my development branch on the base branch (develop).
  • In case of a new plugin, I have created the new packaging directory accordingly.
  • I have implemented automated tests related to my commits.
    • Data used for automated tests are anonymized.
  • I have reviewed all the help messages in all the .pm files I have modified.
    • All sentences begin with a capital letter.
    • All sentences end with a period.
    • I am able to understand all the help messages, if not, exchange with the PO or TW to rewrite them.
  • After having created the PR, I will make sure that all the tests provided in this PR have run and passed.

Summary by Aikido

Security Issues: 0 🔍 Quality Issues: 8 Resolved Issues: 0

🚀 New Features

  • Introduced a new Waystream SNMP plugin with multiple monitoring modes.
  • Added SFP and hardware sensor modes for temperature, voltage, and fans.

⚡ Enhancements

  • Implemented statefile caching to reduce SNMP requests and improve performance.

🐛 Bugfixes

  • Fixed cpu-detailed percentage calculation to correctly compute CPU usage.

🔧 Refactors

  • Refactored outputs and discovery, added interface names and connector filtering.

More info

my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);

if (defined($self->{option_results}->{filter_connector}) && $self->{option_results}->{filter_connector} ne '' &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using --filter-connector value directly in a regex ($self->{option_results}->{filter_connector}) allows regex injection / ReDoS. Escape (quotemeta) or validate the filter before using in /.../.

Details

✨ AI Reasoning
​The code uses an option value directly inside a regular expression match to filter connector types. If the option value is attacker-controlled or crafted (e.g., via CLI or API), it can change the regex semantics, cause catastrophic backtracking (ReDoS), or match unintended values. Properly escaping (quotemeta) or validating allowed values should be used before embedding into a regex.

🔧 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 $results = {};
foreach (keys %$sfp_ports) {
if (defined($self->{option_results}->{filter_port}) && $self->{option_results}->{filter_port} ne '' &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using --filter-port value directly in a regex ($_ !~ /$self->{option_results}->{filter_port}/) allows regex injection / ReDoS. Escape (quotemeta) or validate the filter before use.

Details

✨ AI Reasoning
​The code filters port indices by embedding the user-provided --filter-port into a regular expression. An attacker-supplied pattern could alter matching semantics or cause catastrophic backtracking. The filter value should be escaped or validated against an allowed pattern before using in a regex.

🔧 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;
}

if (defined($self->{option_results}->{filter_serial}) && $self->{option_results}->{filter_serial} ne '' &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Using --filter-serial value directly in a regex ($sfp_ports->{$_}->[0] !~ /$self->{option_results}->{filter_serial}/) allows regex injection / ReDoS. Escape (quotemeta) or validate the filter before use.

Details

✨ AI Reasoning
​The code filters SFP serials by embedding the user-provided --filter-serial into a regular expression. An attacker-supplied pattern could alter matching semantics or cause catastrophic backtracking. The filter value should be escaped or validated against an allowed pattern before using in a regex.

🔧 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

}

if (defined($self->{option_results}->{add_interface_name}) &&
defined($self->{option_results}->{filter_interface}) && $self->{option_results}->{filter_interface} ne '' &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

User-provided 'filter_interface' is interpolated directly into a regex (/$self->{option_results}->{filter_interface}/). Escape or validate this pattern before use.

Details

✨ AI Reasoning
​The code performs a regex match using a user-provided 'filter_interface' value when --add-interface-name is set. The direct interpolation into /.../ without escaping allows crafted input to control the regex and could cause ReDoS or incorrect filtering.

🔧 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

use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::statefile;
use Safe;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Introduces runtime code evaluation via Safe->reval using user-provided regex; avoid executing dynamic code from inputs or validate/sanitize thoroughly.

Details

✨ AI Reasoning
​The changes introduce dynamic code execution via the Safe module. A package-level shared variable ($assign_var) is set from external input and then a string built from user-supplied display_transform_src/display_transform_dst is passed to Safe->reval for execution. This is effectively running dynamically constructed Perl code at runtime, which can be used to perform unexpected operations or bypass reviews. Even though Safe is used, re-evaluating user-provided regex replacements is risky and can lead to unintended behavior or be exploited. The relevant additions are the Safe usage and share (lines where Safe is instantiated and share is called), assignment to the shared variable, and the reval invocation along with the die on $@. These were added in this diff and introduce the eval-like behavior.

🔧 How do I fix it?
Ensure code is transparent and not intentionally obfuscated. Avoid hiding functionality from code review. Focus on intent and deception, not specific patterns.

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

$self->{statefile_cache} = centreon::plugins::statefile->new(%options);

$self->{safe} = Safe->new();
$self->{safe}->share('$assign_var');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shares global variable ('$assign_var') into Safe compartment used for reval; exposing globals to evaluated code increases risk of misuse.

Details

✨ AI Reasoning
​The changes call $self->{safe}->share('$assign_var'), exposing a global into the Safe compartment. Sharing globals into an evaluated context broadens what the evaluated code can access and was added here, contributing to potential covert behavior or vulnerabilities.

🔧 How do I fix it?
Ensure code is transparent and not intentionally obfuscated. Avoid hiding functionality from code review. Focus on intent and deception, not specific patterns.

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

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

our $assign_var = $options{value};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Assigning external input to shared global ($assign_var) used in Safe->reval enables execution of user-controlled data; avoid sharing raw input into eval contexts.

Details

✨ AI Reasoning
​The diff adds a package/global variable assignment (our $assign_var = $options{value}) which is then used inside the Safe->reval context. This pattern couples external input to dynamic evaluation, increasing the attack surface even though Safe is used. The new assignment was introduced here and directly contributes to the runtime execution flow.

🔧 How do I fix it?
Ensure code is transparent and not intentionally obfuscated. Avoid hiding functionality from code review. Focus on intent and deception, not specific patterns.

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

if (defined($self->{option_results}->{display_transform_src})) {
$self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst}));

$self->{safe}->reval("\$assign_var =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

User-provided display_transform_src/display_transform_dst are interpolated into a Safe->reval call ("$assign_var =~ s{...}{...}"). Avoid evaluating user input as code; use a precompiled regex (qr//) and apply it safely or validate/escape inputs before use.

Details

✨ AI Reasoning
​The code builds and evaluates Perl code at runtime using user-controlled values. It assigns the display value to a package variable and then calls Safe->reval with a string that interpolates option values into a Perl substitution expression. Untrusted input in display_transform_src or display_transform_dst can alter the evaluated code or produce unintended behavior. Evaluating user-provided patterns as code is risky and can lead to code injection or crashes.

🔧 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant