Summary
Follow-up audit found severe Backup API issues that can either break backup/restore endpoints at runtime or allow backup restore/delete path checks to match unintended sibling directories.
Findings
1. Severe: Backup endpoints require JobQueue, but LocalApi does not register it
BackupEndpoints calls:
ctx.RequestServices.GetRequiredService<JobQueue>()
for backup create, restore, and job status. However LSPDFRManager.LocalApi/Program.cs builds the app without registering JobQueue in DI.
Impact: backup create/restore/status endpoints can fail at runtime with a missing service exception instead of creating or returning job state.
Expected fix: register JobQueue before builder.Build():
builder.Services.AddSingleton<JobQueue>();
Add endpoint tests that boot the Local API and call:
POST /api/v1/backups
POST /api/v1/backups/restore
GET /api/v1/jobs/{jobId}
2. Severe: Backup restore/delete containment check uses unsafe prefix matching
Backup restore/delete resolve a target path and check:
resolvedPath.StartsWith(resolvedRoot, StringComparison.OrdinalIgnoreCase)
without forcing resolvedRoot to end with a directory separator. A sibling path such as C:\Backups2\file.zip can match root C:\Backups by string prefix.
Impact: a crafted backup file name can pass containment logic for unintended sibling directories if routing/model binding provides the path segment in a compatible form.
Expected fix: use a robust containment helper, for example:
var root = Path.GetFullPath(backupPath)
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
+ Path.DirectorySeparatorChar;
var candidate = Path.GetFullPath(Path.Combine(root, request.FileName));
if (!candidate.StartsWith(root, StringComparison.OrdinalIgnoreCase))
return Results.BadRequest("Invalid file name.");
Also reject rooted file names, path separators where only a file name is expected, and non-.zip extensions before file I/O.
Acceptance criteria
Audit note
This issue intentionally tracks only severe bugs. Lower-severity diagnostics such as stale health version or misleading display messages should be handled separately if desired.
Summary
Follow-up audit found severe Backup API issues that can either break backup/restore endpoints at runtime or allow backup restore/delete path checks to match unintended sibling directories.
Findings
1. Severe: Backup endpoints require
JobQueue, but LocalApi does not register itBackupEndpointscalls:for backup create, restore, and job status. However
LSPDFRManager.LocalApi/Program.csbuilds the app without registeringJobQueuein DI.Impact: backup create/restore/status endpoints can fail at runtime with a missing service exception instead of creating or returning job state.
Expected fix: register
JobQueuebeforebuilder.Build():Add endpoint tests that boot the Local API and call:
POST /api/v1/backupsPOST /api/v1/backups/restoreGET /api/v1/jobs/{jobId}2. Severe: Backup restore/delete containment check uses unsafe prefix matching
Backup restore/delete resolve a target path and check:
without forcing
resolvedRootto end with a directory separator. A sibling path such asC:\Backups2\file.zipcan match rootC:\Backupsby string prefix.Impact: a crafted backup file name can pass containment logic for unintended sibling directories if routing/model binding provides the path segment in a compatible form.
Expected fix: use a robust containment helper, for example:
Also reject rooted file names, path separators where only a file name is expected, and non-
.zipextensions before file I/O.Acceptance criteria
JobQueueis registered in LocalApi DI.C:\BackupsvsC:\Backups2.Audit note
This issue intentionally tracks only severe bugs. Lower-severity diagnostics such as stale health version or misleading display messages should be handled separately if desired.