-
Notifications
You must be signed in to change notification settings - Fork 377
Remote-host attachments sharing a sanitized name silently overwrite each other (post-sanitization basename collision) #387
Copy link
Copy link
Open
Labels
P1Urgent regression or broken agent/channel workflow affecting real users now.Urgent regression or broken agent/channel workflow affecting real users now.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:data-lossThis issue is about lost, corrupted, or silently dropped user/session/config data.This issue is about lost, corrupted, or silently dropped user/session/config data.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1Urgent regression or broken agent/channel workflow affecting real users now.Urgent regression or broken agent/channel workflow affecting real users now.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:data-lossThis issue is about lost, corrupted, or silently dropped user/session/config data.This issue is about lost, corrupted, or silently dropped user/session/config data.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Version: oracle 0.18.0 (
main@083bba7e), remote-host path (ORACLE_REMOTE_HOST/browser.remoteHost)Related to #385, but a distinct mechanism on a different path. #385 is the local browser upload path, where
attachmentDataTransfer.tsbuilds each browserFilefrompath.basename(). This one happens server-side, before the browser is involved at all, and survives any client-side guard on original basenames.What happens
sanitizeNameinsrc/remote/server.ts:722maps every character outside[a-zA-Z0-9._-]to_:At
src/remote/server.ts:229-238that sanitized name becomes the write path, and each attachment entry then records that path:Two attachments whose names differ only in characters the regex folds therefore resolve to the same
filePath.writeFileoverwrites the first payload, and both pushed entries point at the surviving file. The fallback loop at:249-258has the same shape.Concretely,
a b.txtanda_b.txtboth sanitize toa_b.txt.Why it is easy to miss
The names are genuinely distinct on the client, so any collision check on original basenames passes. The divergence only appears after sanitization, on the server, by which point the write has already happened. There is no warning and no count mismatch, so the run reports the full number of files.
Impact
Same class as #385: silent content loss, with the surviving file wearing a plausible name. A caller sees the expected file count and a successful run while one attachment's content was never sent. The recurring-basename case that makes #385 painful in multi-directory packs applies here too, widened to any pair of names differing only in sanitized characters (spaces being the common one).
Suggested fix
Collision-free path allocation at the write site, rather than a client-side check. Two reasons to prefer the server side:
Suffixing on collision (
a_b.txt,a_b-2.txt) or allocating per-attachment subdirectories both work. Erroring is also defensible for consistency with the #385 guard, though the names here are legitimately distinct from the user's point of view, which argues for allocation over rejection.Not attempted
I did not run a live remote-host session against this; the report is from reading
mainat083bba7e. The mechanism is visible in source and the two loops are unambiguous, but a live confirmation would be worth having before anyone builds on it.