Skip to content

[cisco_ise] Fix NPE in foreach acme-av-pair null guard. - #20622

Merged
vinit-chauhan merged 3 commits into
mainfrom
fix/0-add-an-explicit-ctx-cisco-ise-log-log-details-null-15856128
Aug 19, 2026
Merged

[cisco_ise] Fix NPE in foreach acme-av-pair null guard.#20622
vinit-chauhan merged 3 commits into
mainfrom
fix/0-add-an-explicit-ctx-cisco-ise-log-log-details-null-15856128

Conversation

@ie-ops

@ie-ops ie-ops commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Executive summary

Four if conditions in pipeline_failed_attempts.yml were updated to guard against log_details being null before accessing its keys. Previously, expressions like ctx.cisco_ise?.log?.log_details['acme-av-pair'] would throw a NullPointerException in the foreach processor when log_details itself was absent — the safe-navigation operator ?. only protects against null at the log level, not when subscript-accessing a null map. The fix adds an explicit ctx.cisco_ise?.log?.log_details != null pre-check to all four affected conditions, preventing the NPE for non-first segments of multi-segment CISE_Failed_Attempts messages that carry no log_details payload.

Proposed commit message

[cisco_ise] Fix NPE in foreach acme-av-pair null guard.

Root cause

The foreach processor's if condition uses bracket notation (ctx.cisco_ise?.log?.log_details['acme-av-pair']) without first guarding against log_details itself being null. In Painless, ?. only suppresses the null dereference of the property it directly precedes; when cisco_ise.log.log_details is absent (as it legitimately is for non-first segments of a multi-segment CISE_Failed_Attempts message, where the KV parser produces no output), null['acme-av-pair'] throws a NullPointerException that causes the foreach processor to fail and propagates to the pipeline's on_failure handler.

Approach

Add an explicit ctx.cisco_ise?.log?.log_details != null guard as the first condition in both the foreach and companion kv processor if expressions in pipeline_failed_attempts.yml. The foreach condition at line 275 currently goes straight to bracket access ctx.cisco_ise?.log?.log_details['acme-av-pair'] — Painless's ?. only protects the immediate property step, so when log_details is absent the subsequent bracket dereference throws a NullPointerException. Adding the null guard mirrors the pattern already used in pipeline_passed_authentications.yml and pipeline_tacacs_accounting.yml for the equivalent cisco-av-pair and User-Name fields. A new test fixture line for the multi-segment (segment > 0, no log_details) case will be added to exercise the fixed path.

Implementation

  1. Step 1: In packages/cisco_ise/data_stream/log/elasticsearch/ingest_pipeline/pipeline_failed_attempts.yml, change the foreach processor if condition at line 275 from ctx.cisco_ise?.log?.log_details['acme-av-pair'] != null && ctx.cisco_ise?.log?.log_details['acme-av-pair'] instanceof List to ctx.cisco_ise?.log?.log_details != null && ctx.cisco_ise.log.log_details['acme-av-pair'] != null && ctx.cisco_ise.log.log_details['acme-av-pair'] instanceof List.
  2. Step 2: In the same file, change the companion kv processor if condition at line 290 from ctx.cisco_ise?.log?.log_details['acme-av-pair'] != null && !(ctx.cisco_ise?.log?.log_details['acme-av-pair'] instanceof List) to ctx.cisco_ise?.log?.log_details != null && ctx.cisco_ise.log.log_details['acme-av-pair'] != null && !(ctx.cisco_ise.log.log_details['acme-av-pair'] instanceof List).
  3. Step 3: Add the sanitized event from the issue (a segment 2 of 3 CISE_Failed_Attempts line with no acme-av-pair and no log_details) as a new entry at the end of packages/cisco_ise/data_stream/log/_dev/test/pipeline/test-pipeline-failed-attempts.log.
  4. Step 4: Regenerate / add the corresponding expected output object in packages/cisco_ise/data_stream/log/_dev/test/pipeline/test-pipeline-failed-attempts.log-expected.json for the new test case, verifying event.kind is event (not pipeline_error) and no error.message is set.
  5. Step 5: Bump the patch version in packages/cisco_ise/manifest.yml (1.32.6 → 1.32.7) and prepend a bugfix changelog entry in packages/cisco_ise/changelog.yml.
  6. Step 6: Run elastic-package test pipeline -C packages/cisco_ise to validate the fix and confirm all test cases pass.

Pipeline changes

  • Modify foreach processor (tag foreach_cisco_ise_log_log_details_acme-av-pair_72a6fe4c) if condition: prepend ctx.cisco_ise?.log?.log_details != null && before the existing bracket access, and change remaining ?.log?.log_details[ references in that condition to .log.log_details[ (safe after the null guard).
  • Modify companion kv processor (tag kv_cisco_ise_log_log_details_acme-av-pair_to_cisco_ise_log_acme-av-pair_6cc5cb52) if condition: apply the same null guard prepend so both processors are consistent.

Field / mapping changes

Sanitized error message

Processor 'foreach' with tag 'foreach_cisco_ise_log_log_details_acme-av-pair_72a6fe4c' in pipeline 'logs-cisco_ise.log-pipeline_failed_attempts' failed with message '[on_failure_message]'

Sanitized log (event_sanitized excerpt)

<181>Jun 27 17:54:40 host-1.example.local CISE_Failed_Attempts 000000001234 3 2 alice.johnson, StepData=15=EXAMPLE-AD, TotalAuthenLatency=27, ClientLatency=0, IsMachineIdentity=false, UserAccountControl=512, Model Name=Unknown, Software Version=Unknown, Network Device Profile=Cisco, Location=Location#All Locations, Device Type=Device Type#All Device Types#CORE#Cisco, IPSEC=IPSEC#Is IPSEC Device#No, Migrated_NDGs=Migrated_NDGs#All Migrated_NDGs, Response={AuthenticationResult=Failed; Authen-Reply-Status=Fail; },

Reviewer concerns

  • The changelog and manifest reference PR link https://github.com/elastic/integrations/pull/1 — this placeholder should be updated to the real PR URL before merge.
  • The test fixture's @timestamp (2026-06-27T17:54:40.000Z) is in the future relative to today (2026-08-06), which is fine functionally but reviewers should be aware the sample log line has a forward-dated timestamp.
  • Only acme-av-pair and User-Name guard conditions were patched; any other processors in the pipeline that similarly subscript into log_details without a prior null-check could still be vulnerable — worth a broader audit.

Self-review findings

Risk and classification

  • Plan risk level: low
  • Tags: pipeline, processors, test-fixture
  • Impact: medium

Links

  • Issue: (no issue number)
  • Issue title: cisco_ise.log [PIPELINE_FIX]: Processor 'foreach' with tag 'foreach_cisco_ise_log_log_details_acme-av-…
  • Pipeline case: 5bec7fbc40d5bca1
@ie-ops ie-ops added bugfix Pull request that fixes a bug issue Integration:cisco_ise Cisco ISE source:integration_sentinel The PR was created via the Integration Sentinel pipeline Team:Integration-Experience Security Integrations Integration Experience [elastic/integration-experience] labels Aug 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Elastic Docs Style Checker (Vale)

No issues found on modified lines!


The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.

@haetamoudi
haetamoudi marked this pull request as ready for review August 10, 2026 10:08
@haetamoudi
haetamoudi requested a review from a team as a code owner August 10, 2026 10:08
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/integration-experience (Team:Integration-Experience)

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

🚀 Benchmarks report

To see the full report comment with /test benchmark fullreport

- foreach:
tag: foreach_cisco_ise_log_log_details_acme-av-pair_72a6fe4c
if: "ctx.cisco_ise?.log?.log_details['acme-av-pair'] != null && ctx.cisco_ise?.log?.log_details['acme-av-pair'] instanceof List"
if: "ctx.cisco_ise?.log?.log_details != null && ctx.cisco_ise.log.log_details['acme-av-pair'] != null && ctx.cisco_ise.log.log_details['acme-av-pair'] instanceof List"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🟡 Medium confidence: high path: packages/cisco_ise/data_stream/log/elasticsearch/ingest_pipeline/pipeline_failed_attempts.yml:275

The same unguarded log_details map access that is fixed here still exists in two sibling pipelines of this data stream; add the identical log_details != null guard to pipeline_radius_accounting.yml and pipeline_authentication_flow_diagnostics.yml so those categories do not keep hitting the NPE.

Details

The guard added here is correct: ctx.cisco_ise?.log?.log_details returns null when the kv processor that builds log_details was skipped, and Painless then throws on the ['acme-av-pair'] index access because ?. does not propagate through a map subscript. The same expression shape is still present, unguarded, in two other pipelines of the same data stream:

  • packages/cisco_ise/data_stream/log/elasticsearch/ingest_pipeline/pipeline_radius_accounting.yml line 261 - ctx.cisco_ise?.log?.log_details['Event-Timestamp'] != null
  • packages/cisco_ise/data_stream/log/elasticsearch/ingest_pipeline/pipeline_authentication_flow_diagnostics.yml line 166 - ctx.cisco_ise?.log?.log_details['NAS-IP-Address'] != null

Both of those pipelines have the identical preconditions that make log_details absent: they grok cisco_ise.log.log_details_raw for segments where cisco_ise.log.segment.number > 0, then feed it to the same kv processor (field_split: ', (?=[^,=]+=)') with ignore_failure: true. A continuation segment starts with a value fragment that has no =, so the kv processor throws on the first token, is swallowed by ignore_failure, and cisco_ise.log.log_details is never created - exactly the case this PR reproduces for CISE_Failed_Attempts. CISE_RADIUS_Accounting and CISE_Authentication_Flow_Diagnostics messages segment the same way, so those two conditions will throw on the same input class and route the event to the pipeline on_failure handler as event.kind: pipeline_error.

Since this PR already bumps the package version and adds the changelog entry, folding the two remaining occurrences in keeps the bug class closed in one release rather than leaving two known NPEs behind.

Recommendation:

Apply the same null guard to the two remaining conditions.

pipeline_radius_accounting.yml (line 261):

      if: ctx.cisco_ise?.log?.log_details != null && ctx.cisco_ise.log.log_details['Event-Timestamp'] != null

pipeline_authentication_flow_diagnostics.yml (line 166):

      if: ctx.cisco_ise?.log?.log_details != null && ctx.cisco_ise.log.log_details['NAS-IP-Address'] != null

An equivalent single-expression form that is also null-safe, if you prefer it over the two-part guard:

      if: ctx.cisco_ise?.log?.log_details?.get('Event-Timestamp') != null

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

<182>Apr 27 11:11:47 hijk.xyz.com CISE_RADIUS_Accounting 0000070618 1 0 2020-04-27 11:11:47.028075 -08:00 0091827141 3000 NOTICE Radius-Accounting: RADIUS Accounting start request, ConfigVersionId=33, Device IP Address=81.2.69.145, RequestLatency=6, NetworkDeviceName=WNBU-WLC1, User-Name=nisehorrrrn, NAS-IP-Address=81.2.69.145, NAS-Port=13, Framed-IP-Address=89.160.20.112, Class=CACS:0a2025060001794f52cfa877:hijk.xyz.com/176956368/1092772, Called-Station-ID=00-24-97-69-7a-c0, Calling-Station-ID=d4-ca-6d-14-87-3b, NAS-Identifier=Acme_fe:56:00, Acct-Status-Type=Start, Acct-Session-Id=00000000/d4:ca:6d:14:87:3b/20879, Acct-Authentic=RADIUS, Event-Timestamp=1389340795, NAS-Port-Type=Wireless - IEEE 802.11, Tunnel-Type=(tag=0) VLAN, Tunnel-Medium-Type=(tag=0) 802, Tunnel-Private-Group-ID=(tag=0) 70, Airespace-Wlan-Id=1, AcsSessionID=hijk.xyz.com/176956368/1092777, SelectedAccessService=Default Network Access, Step=11004, Step=11017, Step=15049, Step=15008, Step=15048, Step=15048, Step=15048, Step=15004, Step=15006, Step=11005, NetworkDeviceGroups=Location#All Locations#SJC#WNBU, NetworkDeviceGroups=Device Type#All Device Types#Wireless#WLC, CPMSessionID=0a222bc0000000d123e111f0, AllowedProtocolMatchedRule=Default, Location=Location#All Locations#SJC#WNBU, Device Type=Device Type#All Device Types#Wireless#WLC
<182>Apr 27 11:18:08 tuv.w.xyz.com CISE_RADIUS_Accounting 0000142722 1 0 2020-04-27 11:18:08.144167 -08:00 0096217580 3001 NOTICE Radius-Accounting: RADIUS Accounting stop request, ConfigVersionId=33, Device IP Address=81.2.69.145, RequestLatency=4, NetworkDeviceName=WNBU-WLC1, User-Name=businesskent, NAS-IP-Address=81.2.69.145, NAS-Port=13, Framed-IP-Address=89.160.20.112, Class=CACS:0a202506000193a252d04b55:tuv.w.xyz.com/176956368/1154568, Called-Station-ID=00-24-97-69-7a-c0, Calling-Station-ID=5c-0a-5b-43-3f-79, NAS-Identifier=Cisco_fe:56:00, Acct-Status-Type=Stop, Acct-Delay-Time=0, Acct-Input-Octets=43000, Acct-Output-Octets=140998, Acct-Session-Id=0000AAAA/5c:0a:5b:43:3f:79/24927, Acct-Authentic=RADIUS, Acct-Session-Time=209, Acct-Input-Packets=471, Acct-Output-Packets=262, Acct-Terminate-Cause=User Request, undefined-52=
<182>Apr 27 11:18:08 tuv.w.xyz.com CISE_RADIUS_Accounting 0000142672 2 1 ConfigVersionId=35, Device IP Address=81.2.69.144, RequestLatency=8, NetworkDeviceName=WNBU-WLC1, User-Name=businesskent, NAS-IP-Address=81.2.69.145, NAS-Port=17, Framed-IP-Address=89.160.20.112, Class=CACS:0a202506000193a252d04b55:tuv.w.xyz.com/176956368/1154568, Called-Station-ID=00-24-97-69-7a-c0, Calling-Station-ID=5c-0a-5b-43-3f-79, NAS-Identifier=Cisco_fe:56:00, Acct-Status-Type=Stop, Acct-Delay-Time=0, Acct-Input-Octets=43000, Acct-Output-Octets=140998, Acct-Session-Id=0000AAAA/5c:0a:5b:43:3f:79/24927, Acct-Authentic=RADIUS, Acct-Session-Time=209, Acct-Input-Packets=471, Acct-Output-Packets=262, Acct-Terminate-Cause=User Request, undefined-52=
<182>Jun 27 17:54:40 host-1.example.local CISE_RADIUS_Accounting 000000001234 3 2 alice.johnson, StepData=15=EXAMPLE-AD, TotalAuthenLatency=27, ClientLatency=0, Response={AuthenticationResult=Failed; Authen-Reply-Status=Fail; },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: 🔵 Low confidence: medium path: packages/cisco_ise/data_stream/log/_dev/test/pipeline/test-pipeline-radius-accounting.log:4

The new regression fixtures are continuation segments with no timestamp in the message body, so @​timestamp is derived from the year-less syslog header and the expected files pin 2026 - these two tests will fail once the calendar year rolls over. Use a segment-0 line carrying a full ISO timestamp instead.

Details

This line and the matching one in test-pipeline-authentication-flow-diagnostics.log (line 11) are segment 2 of 3, so the sub-pipeline's segment>0 grok extracts only log_details_raw and never a body timestamp. @​timestamp therefore comes from default.yml's MMM [ ]d[d] HH:mm:ss parse of the syslog header, which has no year, so the ingest date processor fills in the current year. The regenerated expected files hard-code "2026-06-27T17:54:40.000Z"; from 2027-01-01 the same input parses to 2027-06-27 and both pipeline tests fail.

This is not introduced by the PR - the pre-existing Mar 28 continuation line in the authentication-flow fixture has the same property (expected "2026-03-28T11:23:25.000Z") - but the delta adds two more year-dependent cases. It is avoidable here: the regression only needs cisco_ise.log.log_details to be absent, which happens because the first token of log_details_raw (alice.johnson) has no =, so the kv processor throws and is swallowed by its ignore_failure: true. A segment-0 line reproduces that identically while also carrying a body ISO timestamp that pins the year.

Recommendation:

Make the fixture a first segment so the body timestamp (which includes an explicit year and offset) drives @​timestamp, keeping the value-less leading token that makes the kv fail and leaves log_details absent:

<182>Jun 27 17:54:40 host-1.example.local CISE_RADIUS_Accounting 000000001234 1 0 2026-06-27 17:54:40.000 +00:00 000000005678 3000 NOTICE Radius-Accounting: RADIUS Accounting start request, alice.johnson, StepData=15=EXAMPLE-AD,

Apply the same shape to test-pipeline-authentication-flow-diagnostics.log (line 11) and regenerate both -expected.json files with elastic-package test pipeline -g.


🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@vera-review-bot

Copy link
Copy Markdown

Review summary

Issues found across the latest commits f56443a — 1 low
  • 🔵 The new regression fixtures are continuation segments with no timestamp in the message body, so @​timestamp is derived from the year-less syslog header and the expected files pin 2026 - these two tests will fail once the calendar year rolls over. Use a segment-0 line carrying a full ISO timestamp instead. (link) (Unresolved)
Issues found across earlier commits 87d896f — 1 medium
  • 🟡 The same unguarded log_details map access that is fixed here still exists in two sibling pipelines of this data stream (link) (Unresolved)

A new commit triggers another review — at most once every 15 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

💚 Build Succeeded

History

@mergify

mergify Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request
@vinit-chauhan
vinit-chauhan merged commit 9e06ca0 into elastic:main Aug 19, 2026
10 checks passed
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

Package cisco_ise - 1.32.11 containing this change is available at https://epr.elastic.co/package/cisco_ise/1.32.11/

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

Labels

bugfix Pull request that fixes a bug issue Integration:cisco_ise Cisco ISE source:integration_sentinel The PR was created via the Integration Sentinel pipeline Team:Integration-Experience Security Integrations Integration Experience [elastic/integration-experience]

4 participants