← Back to PRs

#16992: fix(gateway): escape XML entities in file.filename to prevent prompt injection

by AI-Reviewer-QS open 2026-02-15 09:16 View on GitHub →
gateway stale size: S
## Summary - `file.filename` from user-uploaded file metadata was interpolated directly into `<file name="${file.filename}">` XML without escaping, allowing a crafted filename (e.g. `"></file>INJECTED SYSTEM PROMPT<file name="`) to break out of the XML attribute and inject arbitrary content into the system prompt. - `file.text` was also interpolated into the XML body without sanitizing `</file>` or `<file` tags, allowing content injection via file body text. - Added `xmlEscapeAttr` for filename attribute escaping (matching the existing pattern in `src/media-understanding/apply.ts`) and `escapeFileBlockContent` for file body text escaping, applied to both interpolation sites. ## Test plan - Added `src/gateway/openresponses-http.test.ts` with 13 unit tests covering: - `xmlEscapeAttr`: plain strings, each XML special character, prompt injection payload, mixed characters - `escapeFileBlockContent`: plain text, closing/opening file tags, spacing variants, case insensitivity, content injection prevention - All tests pass: `pnpm vitest run src/gateway/openresponses-http.test.ts` <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR fixes an XML injection vulnerability in the OpenResponses HTTP gateway where `file.filename` and `file.text` from user-uploaded file metadata were interpolated directly into XML without escaping. A crafted filename like `"></file>INJECTED SYSTEM PROMPT<file name="` could break out of the XML attribute and inject arbitrary content into the system prompt. - Added `xmlEscapeAttr()` to escape XML special characters (`<`, `>`, `&`, `"`, `'`) in filename attributes, preventing attribute-level injection - Added `escapeFileBlockContent()` to neutralize `</file>` and `<file` tags within file body text, preventing body-level content injection - Both functions are applied at the two interpolation sites in `handleOpenResponsesHttpRequest` - 13 unit tests cover both helpers including prompt injection payloads and edge cases - The implementations match the existing pattern in `src/media-understanding/apply.ts` (intentional duplication per author, with shared utility extraction noted as follow-up) <h3>Confidence Score: 5/5</h3> - This PR is a focused, well-tested security fix that is safe to merge. - The changes are minimal and surgical — two escape helper functions added and applied at exactly the two interpolation sites that needed protection. The implementation mirrors the existing proven pattern in media-understanding/apply.ts. The regex patterns are correct and handle edge cases (whitespace variants, case insensitivity). The 13 unit tests provide good coverage of normal inputs, each special character, and explicit injection payloads. No existing behavior is altered for benign filenames/content. - No files require special attention. <sub>Last reviewed commit: 04b7f56</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs