Skip to content

feat(finding): redact sensitive finding values in API (#7500) - #7587

Open
Hedi (heditar) wants to merge 13 commits into
mainfrom
heditar-sensitive-finding-redaction
Open

feat(finding): redact sensitive finding values in API (#7500)#7587
Hedi (heditar) wants to merge 13 commits into
mainfrom
heditar-sensitive-finding-redaction

Conversation

@heditar

@heditar Hedi (heditar) commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #7500

Credentials discovered during a simulation were returned — and displayed — in cleartext on the Finding page. Sensitive finding types are now flagged and their value is redacted everywhere the REST API serializes it.

What changed

  • Column: new migration adds findings.finding_is_sensitive (default false), backfilled to true for existing Credentials rows.
  • Sensitivity per type: FindingCapableOutputProcessor defaults to non-sensitive; only CredentialsOutputProcessor opts in. OutputProcessorIntegrationTest guards the matrix, so declaring a new sensitive type is deliberate.
  • Redaction: FindingService.redact(...) masks every :-separated part, keeping a two character fragment — admin:motdepassead******:mo******, a part shorter than 5 characters is masked entirely. Applied to the read endpoint, the summary and the search outputs (AggregatedFindingOutput / RelatedFindingOutput), which also expose finding_is_sensitive.

How to test:

  • Create a scenario that generates findings of type credentials, verify that the findings are masked in the UI and in the scenario page. You can also try other finding apis.

Checklist

  • I consider the submitted work as finished
  • I tested the code for its functionality
  • I wrote test cases for the relevant uses case
  • [NA] I added/update the relevant documentation (either on github or on notion)
  • Where necessary I refactored code to improve the overall quality
  • For bug fix -> I implemented a test that covers the bug

Adds a finding_is_sensitive column and its JPA mapping. Each finding-capable
output processor now hardcodes the sensitivity of the finding type it produces:
Credentials is the only sensitive one today, since its value is a
username:password or username:hash pair, while every other processor emits
usernames, hosts, CVEs, ports or free text.

A sensitive finding value is redacted whenever the API serializes it (entity,
aggregated/related search outputs and finding summary): the identity part is
kept so an operator can still tell which account is affected, the secret part
is replaced by a mask. The database keeps the cleartext value, which
deduplication, correlation and attack paths rely on, so the full value of a
sensitive finding cannot be retrieved through the API.

Existing credentials findings are backfilled by the migration so already
detected credentials are redacted too.
Copilot AI lite review requested due to automatic review settings August 24, 2026 19:20
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

📖 Documentation check — ✅ Passed

12 functional file(s), 1 doc file(s) changed.

No documentation gaps detected.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses #7500 by introducing a persisted “sensitive” flag on Finding and ensuring sensitive finding values (notably Credentials) are redacted everywhere the REST API serializes them, while keeping the cleartext value in the database for correlation/deduplication.

Changes:

  • Add findings.finding_is_sensitive (migration + entity + repository upsert support) and propagate a per-processor sensitivity decision into persisted findings.
  • Redact sensitive finding_value at serialization time (Jackson serializer for Finding) and in DTO mappings (FindingMapper, findingSummary) while exposing finding_is_sensitive.
  • Add/adjust backend tests, update docs, and extend frontend API types to include finding_is_sensitive (nice coverage with dedicated redactor tests and API assertions).

Reviewed changes

Copilot reviewed 41 out of 42 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
openaev-model/src/main/java/io/openaev/helper/FindingValueSerializer.java New Jackson serializer that redacts finding_value based on the enclosing Finding sensitivity flag.
openaev-model/src/main/java/io/openaev/helper/FindingValueRedactor.java New redaction utility implementing masking rules (identity-preserving where applicable).
openaev-model/src/main/java/io/openaev/database/repository/FindingRepository.java Extend native upsert to persist/update finding_is_sensitive.
openaev-model/src/main/java/io/openaev/database/model/Finding.java Add finding_is_sensitive field + apply serializer to finding_value.
openaev-front/src/utils/api-types.d.ts Add finding_is_sensitive to relevant frontend API types and clarify docs for redacted values.
openaev-api/src/test/java/io/openaev/utils/fixtures/FindingFixture.java Mark credentials fixture findings as sensitive.
openaev-api/src/test/java/io/openaev/rest/finding/FindingServiceTest.java Update service test calls for the new sensitivity parameter.
openaev-api/src/test/java/io/openaev/rest/finding/FindingApiTest.java Assert API redaction + finding_is_sensitive behavior and verify DB keeps cleartext.
openaev-api/src/test/java/io/openaev/output_processor/OutputProcessorIntegrationTest.java Guard sensitivity matrix across all finding-capable processors.
openaev-api/src/test/java/io/openaev/output_processor/CredentialsOutputProcessorTest.java Assert credentials processor is flagged sensitive.
openaev-api/src/test/java/io/openaev/helper/FindingValueRedactorTest.java New unit tests for redaction rules and entity serialization behavior.
openaev-api/src/main/java/io/openaev/utils/mapper/FindingMapper.java Redact value + expose sensitivity in aggregated/related finding DTOs.
openaev-api/src/main/java/io/openaev/rest/finding/form/FindingSummaryOutput.java Add finding_is_sensitive and clarify that finding_value may be redacted.
openaev-api/src/main/java/io/openaev/rest/finding/form/AggregatedFindingOutput.java Add finding_is_sensitive and clarify redaction semantics in schema docs.
openaev-api/src/main/java/io/openaev/rest/finding/FindingWriter.java Thread sensitivity into persistence calls.
openaev-api/src/main/java/io/openaev/rest/finding/FindingService.java Propagate sensitivity through finding generation and redact in summary output.
openaev-api/src/main/java/io/openaev/output_processor/FindingCapableOutputProcessor.java Add per-processor sensitivity flag and pass it into finding generation (contains a blocking parameter-order bug).
openaev-api/src/main/java/io/openaev/output_processor/VulnerabilityOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/UsernameOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/TextOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/SidOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/ShareOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/PortScanOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/PortOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/PasswordPolicyOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/NumberOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/KerberoastableAccountOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/IPv6OutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/IPv4OutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/GroupOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/FileOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/EmailOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/DelegationOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/CVEOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/CredentialsOutputProcessor.java Pass SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/ComputerOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/AsreproastableAccountOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/AdminUsernameOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/ActionOutputOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/output_processor/AccountWithPasswordNotRequiredOutputProcessor.java Pass NOT_SENSITIVE to the finding-capable base constructor.
openaev-api/src/main/java/io/openaev/migration/V6_20260824180000000__Add_finding_is_sensitive.java Add and backfill finding_is_sensitive with idempotent DDL/DML.
docs/docs/usage/evaluate/findings/findings.md Document sensitive findings behavior and clarify that secrets are not deleted from DB.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@heditar
Hedi (heditar) marked this pull request as draft August 25, 2026 07:56
Hedi (heditar) and others added 11 commits August 25, 2026 10:10
#7500)

Add a convenience constructor on FindingCapableOutputProcessor defaulting
to NOT_SENSITIVE so only processors emitting secret material need to opt
in explicitly. The type/sensitivity matrix in OutputProcessorIntegrationTest
guards the default.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
#7500)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Drop the model-side FindingValueRedactor/FindingValueSerializer pair and
keep the redaction in the API layer: FindingService.redact is used by the
summary and the search mappers, and the read endpoint redacts the entity
in a read only transaction so the cleartext value is never flushed back.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Password policy findings disclose the target password policy (minimum
length, complexity, lockout...), which is exploitable material: they are
now redacted like credentials, keeping the policy key visible.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Drop the identity-part exception: a sensitive value now always keeps a
two character fragment, so a credential value no longer discloses the
account name.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
A credential value no longer discloses the account name: each part
separated by a colon keeps only a two character fragment, so
admin:motdepasse is returned as ad******:mo******.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@heditar
Hedi (heditar) marked this pull request as ready for review August 25, 2026 14:07
@heditar Hedi (heditar) added filigran team Item from the Filigran team. feature Type: new feature or capability (feat:). enterprise edition Feature part of the Enterprise Edition license. labels Aug 27, 2026
…7500)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enterprise edition Feature part of the Enterprise Edition license. feature Type: new feature or capability (feat:). filigran team Item from the Filigran team. High risk Medium risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(finding): finding page data analysis

2 participants