feat(backend): /api/persons — query length cap, limit enforcement, response DTO #633
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
The frontend at
MentionDropdown.svelteandPersonMentionEditor.svelte(PR #629) defends against amplification attacks with client-sidemaxlength="100"on the search input and&limit=5on the fetch URL. Both are advisory only — any script in a compromised tab can callfetch('/api/persons?q=' + 'A'.repeat(100000)). The backendPersonControlleris currently unbounded.Additionally, the response shape leaks
notes,alias, etc. to clients that only need name/dates for typeahead (CWE-200).Required changes
PersonController.search: add@Size(max = 100) @RequestParam String q(or equivalent Bean Validation). 414/400 on overlong queries (CWE-400, CWE-602).?limit=enforcement: read@RequestParam(defaultValue = "20") @Min(1) @Max(50) Integer limitand slice service result accordingly.PersonSummaryDTO { id, displayName, birthYear, deathYear, personType, familyMember }— stripnotes,alias,titlefrom the search response. Update OpenAPI annotations to drive frontend type regeneration.Acceptance
code = INVALID_INPUT.PersonSummaryDTOexposed via OpenAPI; frontend regenerates and uses it.Personcast inrunSearchupdated toPersonSummaryDTO(separate PR).Reviewer rationale: Markus #10919/#10959, Nora #10933/#10969.
Additional concern — CWE-770 (Resource throttling)
Capping query length blocks one DoS vector but
/api/personsitself has no per-principal rate limit. Even with a 100-char cap, an authenticated tab (or a compromised one) can call the endpoint 10,000 times in a tight loop./api/persons— e.g. Bucket4j filter or a Spring SecurityOncePerRequestFilterkeyed on principal/session. Suggested envelope: 20 rps burst, 5 rps sustained, tunable. Frontend self-limits at ~6.7 rps (150 ms debounce, one inflight), so this allows ~3× headroom for autofocus/batch use while still throttling abuse.code = TOO_MANY_REQUESTS(or the existing rate-limit error code), and burst recovers after the bucket refills./api/personsinto whatever the framework exposes."Reviewer rationale: Nora #11076 (CWE-770) on PR #629 round 3; WARN-logging sub-bullet per Markus polish on PR #629 round 4 (#11204).