fix(security): wrap the structured JSON block of TM plan tools (complete injection wrap) - #437
Merged
gaurav-singh-9227 merged 1 commit intoSep 25, 2026
Conversation
The earlier fix wrapped the description in the human-readable header of getTestPlan / getSubTestPlan, but the same response also emits a second content block — a raw JSON dump of the full plan object — where the description (and other free-text fields) were returned UNWRAPPED. An injection payload in a shared plan description therefore still reached the model verbatim via that block. Wrap the JSON dump with wrapUntrusted as well, so untrusted plan content is framed as data in every content block. Adds a test asserting the payload never appears outside an UNTRUSTED wrapper. Ref: GHSA-9w6g-vr6g-7jqx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Central YAML (base), Organization UI (inherited), Workspace UI (inherited) Review profile: ASSERTIVE Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
gaurav-singh-9227
approved these changes
Sep 25, 2026
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.
What & why
Follow-up to the TM prompt-injection hardening (GHSA-9w6g-vr6g-7jqx).
The earlier change wrapped the
descriptionin the human-readable header ofgetTestPlan/getSubTestPlan. But each of those tools returns a secondcontent block — a raw
JSON.stringify(...)dump of the full plan object —where the
description(and other free-text likename) was still emittedunwrapped. Since the model reads every content block, an injection payload
placed in a shared plan description still reached it verbatim, so the vector
was not fully closed.
Verified by running the real tools with a payload description: the header was
wrapped, but the JSON block returned the raw payload.
Change
wrapUntrusted(...)in bothget-testplan.tsandget-sub-testplan.ts, so untrusted backend content is framed as data inevery content block.
tests/tools/tm-desc-wrap.test.ts— exercises the real functions(existing suite mocks them) and asserts the payload never appears outside an
UNTRUSTEDwrapper in any block.Test
tsc, eslint: cleantests/tools/tm-desc-wrap.test.ts: 2 passingtests/tools/testmanagement.test.ts: 75 passing (unchanged)🤖 Generated with Claude Code