GET /api/persons leaks PersonSummaryDTO.notes to typeahead clients (CWE-200) #374
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Surfaced during PR #373 review by Nora Steiner (@nullx) — comment #5618, concern #3.
PR #373 introduces a Tiptap-based person mention typeahead in
PersonMentionEditor.svelte. The component fetchesGET /api/persons?q=<query>on every keystroke after@and renders the response in a dropdown for the transcriber.Finding
PersonController.getPersons()returnsList<PersonSummaryDTO>. The DTO interface (backend/src/main/java/org/raddatz/familienarchiv/dto/PersonSummaryDTO.java) currently exposes:Person.notesis described in the entity itself as "Optional: Free-text biographical notes" — i.e. it is intended to hold sensitive biographical content, possibly including living-relative information, medical/personal observations, or unpublished family history.Every transcriber typing
@in the editor causesnotesfor every matched person to be transmitted to the browser. A determined user can scrape all notes simply by typing single letters and inspecting the network panel — without needing direct access to the persons admin page.This is a CWE-200 (Information Exposure) issue: the API over-exposes data the typeahead does not need.
Acceptance Criteria
PersonTypeaheadDTO) returning only fields the dropdown actually renders:id,title,firstName,lastName,personType,birthYear,deathYear,displayName(derived). NOnotes, NOalias, NOdocumentCount, NOisFamilyMemberunless the typeahead UI uses them./api/persons?q=…&shape=typeahead) that returns the new DTO. The list page (/persons) keeps using the currentPersonSummaryDTO.PersonMentionEditor.sveltefetch URL switches to the typeahead variant; types regenerated.PersonControllerTestasserts the typeahead response does NOT includenotes(lock down the API surface — Nora explicitly recommended this).Personcast in the dropdown with the new typeahead-safe DTO type so a future field-leak in the wide DTO doesn't silently re-leak.Non-functional
Out of scope
/persons) and detail page may continue to exposenotesto readers withREAD_ALLpermission — that is the intended privilege level for that route.Source
Nora Steiner, PR #373 review, 2026-04-29.