feat(attack-path): causal chain view, finding-panel correctness and drawer polish (#6647) - #6964
Conversation
|
/review docs
|
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (27.11%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #6964 +/- ##
============================================
+ Coverage 44.57% 44.93% +0.35%
Complexity 9327 9327
============================================
Files 2681 2681
Lines 80357 80440 +83
Branches 12036 12066 +30
============================================
+ Hits 35823 36144 +321
+ Misses 41918 41675 -243
- Partials 2616 2621 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
laugiov
left a comment
There was a problem hiding this comment.
One thing worth confirming before merge: in compact mode disablePagination hides the pager, but the fetch still uses the default page size of 20. An attack-path inject from a scan (nmap, nuclei, netexec) often has more than 20 distinct findings, so the drawer would show 20 and silently hide the rest, with no "20 of N" and no way to reach the others. totalElements is already tracked in PaginationComponentV2, so a small "showing 20 of N" with a link to the inject's full Findings list (or a larger compact page size) would keep it from reading as "this inject has 20 findings". Is capping at 20 intended here?
|
Good catch — fixed in c756b81. In compact mode I now raise the page size to 100 (covers the vast majority of scans without a pager), and when a run still produces more, a "Showing X of N findings — open the inject to see them all." note appears (total tracked from |
e7428e0 to
11aed7a
Compare
…arge/center the empty state (#6647)
…tion) and findings table fit (#6647)
… use them in the attack-path drawer (#6647)
…ndpoint order on refresh, cap finding value labels to avoid overlap (#6647)
…ed, so scan findings are never silently hidden (#6647)
…e labels don't overlap the node above (#6647)
…roduced finding of the type matches) (#6647)
…r legibility (#6647) A consumed key like `share_name IS_NOT_NULL` matches every produced finding of the type, so the chain view drew one identical "Triggered …" edge per finding — stacking N labels over the consumer node and making a single hub endpoint (one asset, many findings) far less readable than a linear multi-endpoint chain. Draw a single causal edge per (consumer, label), anchored to the matching finding nearest the consumer to minimise crossing. A hub endpoint is now as legible as a linear chain.
…6647) The earlier rebase resolved the lang conflicts with `checkout --theirs`, which replaced each locale file wholesale with the branch's version and dropped the keys main had added (the actions/arsenal rename). Restored every locale from main and re-added only the compact-findings key, so the i18n checker passes again.
…n chain mode (#6647) Clicking a finding in the causal-chain view had three defects: the panel's 'Discovered on' fell back to the literal word 'Endpoint' (no pathFinding/focusedEndpoint in chain mode); clicking a finding whose endpoint missed the collapsed-graph lookup left the previous finding's panel on screen (a share still showed the last portscan); and the producer list was empty for any value the backend id-escapes — a share like \host\NETLOGON encodes with doubled backslashes, so the rebuilt NODE_FINDING|type|value never matched the executions' findingsNodeIds. Carry the finding's origin endpoint node id on findingDetail and resolve the label from either graph; resolve the endpoint from the full graph too and never bail in chain mode; and match producers by the node's actual (already-escaped) id instead of rebuilding it raw.
…path in chain mode (#6647) Clicking a finding walked every edge upstream, including the forward causal ("Triggered …") edges, so a plain portscan click lit the whole downstream kill-chain (the consumer injector and its shares) and every injector that merely reached the shared endpoint. Skip causal edges in the walk and, when the finding's producing injector(s) are known from its executions, don't light the others — so the highlight matches the panel's single producer.
…ve the producing-action flash (#6647) Two chain-mode panel glitches: clicking an injector read 'No findings on this endpoint' whenever it only produced shares, because the injector-findings lookup went through the drawer category endpoint which maps files→"file" and never returns type "share"; and clicking a finding flashed 'no producing action' until the endpoint feed finished loading. Source injector findings from the full graph's per-execution findingsNodeIds (covers every type), and fall back to the full graph's executions for the producing-action list until the feed loads.
…panel (#6647) #6912 now persists per-execution prevention/detection/vulnerability statuses, which the backend aggregates onto each finding node's verdicts (worst-of across producers). Read those instead of the placeholder; the DTO already serialises the exact success/failed/unknown labels the panel expects. Also realign the dedup test to the native 'file' share type (#6972 renamed SMB shares from 'share').
…s drawer (#6647) The drawer is narrow, so the six-column findings table read cramped. Hide first-seen and last-seen (alongside the already-hidden asset groups) so only Type / Value / Assets show.
…ia its canonical node id (#6647) The focused (chokepoint) view rebuilt the finding node id as NODE_FINDING|type|value with the raw value, which never matched the executions' findingsNodeIds for backslash/pipe values — so a share read 'Discovered by (0)'. Resolve the finding's canonical id from the full graph (type-agnostic, correctly escaped) and match producers on that, same as the chain view.
…nder a finding in the drawer (#6647) The category drawer printed item.endpointKey (a raw asset uuid) under each finding value. Resolve it to the endpoint's friendly hostname via endpointLabelByRef, and hide the line when it can't be resolved so no bare id ever surfaces.
…ame lookup (#6647) item.endpointKey is optional, so passing it straight to endpointLabelByRef.get() broke check-ts. Resolve the friendly hostname once with a guard per row.
89710c8 to
13f0513
Compare
Summary
Front follow-ups on the Attack Path view (behind the
ATTACK_PATHflag), extending #6920. Groups the execution-drawer polish with the causal-chain view work, finding-panel correctness fixes, and the front-side alignment with the backend PRs merged in the meantime (#6912 expectations/terminal data, #6972 SMB shares as the nativefiletype).Execution drawer & findings list
FindingListscoped to the inject (searchDistinctFindingsForInjects), so it works for both endpoint and injector-contract executions. Shown only when the execution carries an inject id.FindingListgainscompact+hiddenFieldsprops (defaults unchanged, existing usages untouched):compacthides the search/filters/pagination top bar;hiddenFieldshides columns. In the narrow drawer it drops the asset-groups and first-seen / last-seen columns, leaving Type / Value / Assets.position: absolute; inset: 0, 88px icon, h6 message) instead of a small block stuck at the top.Causal chain view (legibility)
share_name IS_NOT_NULLmatches every produced finding of the type, which stacked N identical "Triggered …" labels over the consumer. Draw a single causal edge per (consumer, label), anchored to the nearest matching finding, so a one-asset/many-findings hub reads as cleanly as a linear chain.IS_NOT_NULLevents (any produced finding of the reconciled type satisfies the event).Finding panel correctness (chain & focused views)
focusedEndpointto fall back on).\and|in node ids, so a share value like\\host\NETLOGONnever matched a rebuiltNODE_FINDING|type|value. Match producers by the node's actual / canonical id instead — fixed in both the chain and focused views.findingsNodeIds): shares now show for an injector that only produced shares, which the drawer category endpoint missed (it mapsfiles→file).Alignment with merged backend PRs
verdicts(prevention / detection / vulnerability, aggregated worst-of across producers) instead of the previous placeholder. The DTO already serialises the exactsuccess/failed/unknownlabels.filetype (feat(attackpath): present SMB share findings as the native file type (#6647) #6972): the causal share reconciliation and the tests usefile.i18n
check-ts and eslint clean; attack-path unit tests green. Verified live against a locally rebuilt backend carrying #6912 + #6972.
Related issue: #6647