[Bug] ThreatEventController.getEvents ignores deviceAgentId filter when severity is set #9

Open
opened 2026-07-01 12:21:29 -04:00 by hiveiq · 0 comments
Owner

Confirmed defect

ThreatEventController.getEvents filters by only ONE parameter at a time due to early-return branch ordering. When severity is present, the method returns before ever evaluating deviceAgentId, so the device filter is silently ignored whenever a severity is also selected.

Code refs (confirmed by reading)

  • src/main/java/com/hiveops/aria/controller/ThreatEventController.java, method getEvents:
    • L43-45: if (severity != null) { return eventRepository.findBySeverityOrderByDetectedAtDesc(severity, pageable); } — returns early.
    • L46-47: if (deviceAgentId != null && !deviceAgentId.isBlank()) { return eventRepository.findByDeviceAgentIdOrderByDetectedAtDesc(...); } — UNREACHABLE when severity is non-null.
  • src/main/java/com/hiveops/aria/repository/ThreatEventRepository.java: only single-field finders exist (findBySeverityOrderByDetectedAtDesc L23, findByDeviceAgentIdOrderByDetectedAtDesc L16). There is no combined findBySeverityAndDeviceAgentId... method.
  • frontend/src/components/ThreatEvents.svelte L53-55: the UI sends BOTH params in the same request (severity: severityFilter || undefined, deviceAgentId: deviceSearch || undefined), and both filters can be active at once (hasActiveFilters = !!severityFilter || !!deviceSearch, L22). So the broken combination is actively reachable from the shipped UI.

Impact

When an operator narrows the Threat Events view to a specific device AND a severity, the device filter is dropped: the table shows events of that severity for ALL devices while the active-filter chips still claim the device filter is applied. This presents misleading/wider-than-requested data and makes the device filter non-functional in the common combined-filter case. Not a security/scoping issue (endpoint is hasRole('BCOS_ADMIN'), no institution scoping involved), but the feature is silently broken.

Suggested fix

Add a combined repository method and route to it when both are present, e.g.:

Page<ThreatEvent> findBySeverityAndDeviceAgentIdOrderByDetectedAtDesc(
        ThreatEvent.ThreatSeverity severity, String deviceAgentId, Pageable pageable);

Then in the controller:

boolean hasDevice = deviceAgentId != null && !deviceAgentId.isBlank();
if (severity != null && hasDevice) {
    return eventRepository.findBySeverityAndDeviceAgentIdOrderByDetectedAtDesc(severity, deviceAgentId, pageable);
}
if (severity != null) { ... }
if (hasDevice) { ... }
return eventRepository.findAllByOrderByDetectedAtDesc(pageable);

(Or replace the manual branching with a JPA Specification/@Query that applies both optional predicates.)

Verified against code via the guide KB verification pass.

## Confirmed defect `ThreatEventController.getEvents` filters by only ONE parameter at a time due to early-return branch ordering. When `severity` is present, the method returns before ever evaluating `deviceAgentId`, so the device filter is silently ignored whenever a severity is also selected. ### Code refs (confirmed by reading) - `src/main/java/com/hiveops/aria/controller/ThreatEventController.java`, method `getEvents`: - L43-45: `if (severity != null) { return eventRepository.findBySeverityOrderByDetectedAtDesc(severity, pageable); }` — returns early. - L46-47: `if (deviceAgentId != null && !deviceAgentId.isBlank()) { return eventRepository.findByDeviceAgentIdOrderByDetectedAtDesc(...); }` — UNREACHABLE when severity is non-null. - `src/main/java/com/hiveops/aria/repository/ThreatEventRepository.java`: only single-field finders exist (`findBySeverityOrderByDetectedAtDesc` L23, `findByDeviceAgentIdOrderByDetectedAtDesc` L16). There is no combined `findBySeverityAndDeviceAgentId...` method. - `frontend/src/components/ThreatEvents.svelte` L53-55: the UI sends BOTH params in the same request (`severity: severityFilter || undefined, deviceAgentId: deviceSearch || undefined`), and both filters can be active at once (`hasActiveFilters = !!severityFilter || !!deviceSearch`, L22). So the broken combination is actively reachable from the shipped UI. ### Impact When an operator narrows the Threat Events view to a specific device AND a severity, the device filter is dropped: the table shows events of that severity for ALL devices while the active-filter chips still claim the device filter is applied. This presents misleading/wider-than-requested data and makes the device filter non-functional in the common combined-filter case. Not a security/scoping issue (endpoint is `hasRole('BCOS_ADMIN')`, no institution scoping involved), but the feature is silently broken. ### Suggested fix Add a combined repository method and route to it when both are present, e.g.: ```java Page<ThreatEvent> findBySeverityAndDeviceAgentIdOrderByDetectedAtDesc( ThreatEvent.ThreatSeverity severity, String deviceAgentId, Pageable pageable); ``` Then in the controller: ```java boolean hasDevice = deviceAgentId != null && !deviceAgentId.isBlank(); if (severity != null && hasDevice) { return eventRepository.findBySeverityAndDeviceAgentIdOrderByDetectedAtDesc(severity, deviceAgentId, pageable); } if (severity != null) { ... } if (hasDevice) { ... } return eventRepository.findAllByOrderByDetectedAtDesc(pageable); ``` (Or replace the manual branching with a JPA `Specification`/`@Query` that applies both optional predicates.) _Verified against code via the guide KB verification pass._
hiveiq added the Bug
Priority
High
labels 2026-07-01 12:21:29 -04:00
johannes was assigned by hiveiq 2026-07-01 12:21:29 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hiveiq-src/hiveops-aria#9