[PPSC-1015] fix(scan): repair dead exploitability filter for graded labels - #233
Merged
Merged
Conversation
…abels
The --include-non-exploitable filter matched zero findings: the backend
exploitability label schema drifted from a boolean ({Exploitable: false})
to a graded one ({Exploitability Level: armis_appsec:exploitability:<level>}),
so the old filter was a no-op. Unit tests passed only because they fed the
filter its own expected literals (mock drift).
- Rewrite as a denylist in a shared internal/scan/exploitability.go: hide a
finding only when an "Exploitability Level" label grades it low or medium.
- Never filter ungraded findings (SCA, container CVEs, false positives) --
absence of a label means "not graded", not "safe".
- Consolidate the duplicated copies from repo.go and image.go.
- Update --include-non-exploitable help text and the filtered-count summary
line to match the graded model.
- Update CHANGELOG and rewrite tests against real backend label strings.
Test Coverage Reporttotal: (statements) 72.4% Coverage by function |
There was a problem hiding this comment.
Pull request overview
Fixes the scan --include-non-exploitable flag being a silent no-op by updating exploitability filtering to match the backend’s graded exploitability labels and deduplicating the filter implementation across repo and image scanning.
Changes:
- Replaced the old boolean/legacy label matcher with a shared
scan.ShouldFilterByExploitabilitythat suppresses only explicitly gradedlow/mediumfindings by default. - Removed duplicated per-scanner exploitability filtering logic and updated related unit tests accordingly.
- Updated CLI help text, human summary text, and the changelog to reflect the new graded exploitability behavior.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| internal/scan/repo/repo.go | Switches repo scan filtering to use shared scan.ShouldFilterByExploitability and removes the legacy matcher. |
| internal/scan/repo/repo_test.go | Updates repo scan tests to validate low/medium graded exploitability filtering behavior. |
| internal/scan/repo/helpers_test.go | Removes obsolete tests for the deleted legacy matcher. |
| internal/scan/image/image.go | Switches image scan filtering to use shared scan.ShouldFilterByExploitability and removes the legacy matcher. |
| internal/scan/image/image_test.go | Updates image scan tests to validate low/medium graded exploitability filtering behavior. |
| internal/scan/image/helpers_test.go | Removes obsolete tests for the deleted legacy matcher. |
| internal/scan/exploitability.go | Adds the shared exploitability label parsing + filtering logic for graded levels. |
| internal/scan/exploitability_test.go | Adds focused table-driven unit tests for graded exploitability parsing/filtering. |
| internal/output/human.go | Updates the human summary filtered-count message to reference low/medium exploitability. |
| internal/cmd/scan.go | Updates --include-non-exploitable help text to reflect graded exploitability semantics. |
| docs/CHANGELOG.md | Documents the bug fix and the graded exploitability behavior under “Fixed”. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
Type of Change
Problem
The
--include-non-exploitablefilter was a silent no-op. It matched on a hardcodedscanner code == 38295677+exploitable == falselabel pair, but the backend's exploitability schema drifted from a boolean (Exploitable: true/false) to a graded one (Exploitability Level: low/medium/high), so the old matcher hit zero findings — the flag did nothing. The filter logic was also duplicated verbatim in both the repo and image scanners, so any fix had to be made in two places.Solution
Replaced the dead matcher with a single exported
scan.ShouldFilterByExploitabilitythat hides only findings explicitly gradedlow/medium, and consolidated the duplicated copies fromrepo.goandimage.gointo the sharedinternal/scan/package. Absence of a label means "not graded" (SCA, container CVEs, false positives) and is always shown — a fail-open posture;highis always shown too.--include-non-exploitablerestores showing every finding, and the flag help and filtered-count summary text were updated to match.Testing
Automated Tests
Manual Testing
make build,make lint(0 issues), andmake test(2636 passed, 71.6% coverage) all pass. New table-driven tests ininternal/scan/exploitability_test.gocover graded levels, the namespaced label value parsing, and the ungraded/empty cases; the obsolete per-scanner tests were removed.Reviewer Notes
The fix is graceful — no flag-day. The same change has landed in the boston-v2 generator, which now emits the graded labels this filter consumes. Note the design choice to treat an absent label as "always show" rather than "filter": this is intentional fail-open behaviour so ungraded findings are never silently hidden.
Checklist