fix(agent): neutralize : in cancellation registry keys to prevent delimiter collision#586
Open
chuenchen309 wants to merge 1 commit into
Open
Conversation
…elimiter collision cancel_key() joins project_id/session_id/run_id with `::`, but normalize_key() only escaped `\` and `/`. Since session_id/run_id are unrestricted strings from the HTTP API body and Tauri commands, a `::`-containing id in one field can collide with a shifted split across two fields — e.g. session_id "a::b" + run_id "c" produces the same registry key as session_id "a" + run_id "b::c". This cross-cancels or cross-drops an unrelated turn's cancellation token. Verified against the real production cancel.rs (compiled + all 5 tests run directly via rustc, working around this environment's missing GTK/pkg-config system libs which block a full `cargo test` of the Tauri crate): the new regression test fails pre-fix and passes post-fix, and the 4 pre-existing tests are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Problem
cancel_key(project_id, session_id, run_id)joins the three fields with aliteral
"::"delimiter, butnormalize_key()only neutralized pathseparators (
\and/), not::session_id/run_idare unrestrictedOption<String>fields (no charsetvalidation, unlike
agent/session.rs'ssanitize_session_id) and arereachable from the local HTTP API's
POST /projects/:id/chatbody and theagent_chat/agent_start_turn_streamTauri commands. When a field containsthe substring
"::", two distinct(session_id, run_id)pairs collapse ontothe same registry key — e.g.
(session_id="a::b", run_id="c")and(session_id="a", run_id="b::c")both key to"p1::a::b::c"— so cancellingone turn cross-cancels an unrelated turn's cancellation token. The no-
run_idprefix-search path in
cancel()has the same exposure.Fix
Extend
normalize_keyto also replace:→_, matching its existing\//→_pattern, so the::delimiter can no longer appear inside afield value.
Test
Added
cancellation_registry_does_not_collide_on_embedded_delimiterto theexisting
#[cfg(test)] mod tests, asserting the two colliding pairs above stayindependent.