diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java
index cbc8f6d1..ffc932e7 100644
--- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java
+++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java
@@ -117,12 +117,17 @@ public class GeschichteService {
*
*
Returns a {@link GeschichteSummary} projection — never carries items, preventing
* LazyInitializationException on the non-transactional list path.
+ *
+ *
Security: {@code null} status always resolves to PUBLISHED — even for blog writers.
+ * Only an explicit {@code DRAFT} request scopes the query to the caller's own drafts.
+ * This prevents CWE-639: a blog writer passing {@code null} must not see all authors' drafts.
*/
public List list(GeschichteStatus status, List personIds, UUID documentId, int limit) {
- GeschichteStatus effective = currentUserHasBlogWrite() ? status : GeschichteStatus.PUBLISHED;
+ boolean isDraftRequest = currentUserHasBlogWrite() && status == GeschichteStatus.DRAFT;
+ GeschichteStatus effective = isDraftRequest ? GeschichteStatus.DRAFT : GeschichteStatus.PUBLISHED;
int safeLimit = limit <= 0 ? DEFAULT_LIMIT : Math.min(limit, MAX_LIMIT);
- UUID authorId = effective == GeschichteStatus.DRAFT ? currentUser().getId() : null;
+ UUID authorId = isDraftRequest ? currentUser().getId() : null;
// When personIds is empty, personCount=0 short-circuits the IN() predicate.
// Pass a sentinel UUID to avoid invalid empty IN() SQL while the predicate is skipped.
diff --git a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java
index 261b5bd9..1d183a3c 100644
--- a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java
+++ b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java
@@ -324,6 +324,7 @@ class GeschichteServiceTest {
@DisplayName("security: DRAFT status scopes to current user only")
void list_with_DRAFT_status_scopes_to_current_user_not_all_authors() {
authenticateAs(writer, Permission.BLOG_WRITE);
+ when(userService.findByEmail(writer.getEmail())).thenReturn(writer);
when(geschichteRepository.findSummaries(any(), any(), any(), anyLong(), any()))
.thenReturn(List.of());