Fix dispatch log data leak for deleted items (#248)#258
Open
Fix dispatch log data leak for deleted items (#248)#258
Conversation
Both GET /api/v2/distributions/:item_id and POST .../retry had a flawed access check that only ran when `item` was truthy. When an item was deleted (null), the check was skipped entirely, leaking dispatch logs and allowing retry triggers for any authenticated user. Add an explicit null check before the access control guard so deleted items return 404 immediately. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jessie-coco
approved these changes
Mar 9, 2026
Contributor
jessie-coco
left a comment
There was a problem hiding this comment.
Codex Review R1: CLEAN
0 P1 + 0 P2 + 0 P3 — no issues found.
Analysis
Bug confirmed: Both GET /api/v2/distributions/:item_id and POST .../retry had an access control bypass — when getItem() returned null (deleted item), the guard if (item && req.v2Auth?.app_id && ...) was skipped entirely, allowing getDispatchLog() to return dispatch data for deleted items without any authorization check.
Fix verified:
- Adds explicit
if (!item) return 404before the access control check in both endpoints - Pattern is consistent with existing null handling (e.g.,
handleGetItemat line 593) - Access control logic for existing items is preserved — the
app_idownership check still runs correctly after the null guard getItem()returnsnullfor non-existent IDs (confirmed in db.js)
Dimensions checked:
- ✅ Correctness: Logic is sound, both endpoints patched symmetrically
- ✅ Security: Data leak closed — deleted items now return 404 before any data retrieval
- ✅ Types & contracts: Response shapes unchanged for valid requests
- ✅ Edge cases: Null/deleted item handled; valid items with wrong app_id still get 403
- ✅ Integration: No callers broken — this is a stricter guard, not a behavior change for valid requests
- ✅ Dead code: None introduced
PR #258 final status: 1 review round, R1 CLEAN.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GET /api/v2/distributions/:item_idandPOST .../retryhad an access control guard that only ran whenitemwas truthy — when an item was deleted (null), the guard was skipped entirelyif (!item) return 404before the access check in both endpointsChanges
server/index.js: Added null check for item before access control in GET and POST dispatch log endpointsTest plan
GET /api/v2/distributions/<deleted_item_id>— should return 404POST /api/v2/distributions/<deleted_item_id>/retry— should return 404🤖 Generated with Claude Code