From fe386b2cd47638b802c4904a0c20ce93fe5cca9b Mon Sep 17 00:00:00 2001 From: SashaMIT Date: Fri, 7 Aug 2026 14:21:42 +0700 Subject: [PATCH] fix(github): sanitize issue comment and sub-issue bodies on read paths Issue and PR title/body responses are passed through sanitize.Sanitize (invisible-glyph, BiDi, HTML-tag and code-fence-metadata stripping), but the two remaining body-bearing read paths were not: - convertToMinimalIssueComment returned comment bodies verbatim, so every comment read delivered raw attacker-controlled content. - GetSubIssues marshalled sub-issues (title+body) verbatim. A hostile comment could therefore carry hidden prompt-injection content (invisible Unicode tag block, BiDi overrides) straight into the model context, bypassing the control applied on every sibling path. Apply the same sanitize.Sanitize call in both places. --- pkg/github/issues.go | 9 +++++++++ pkg/github/minimal_types.go | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pkg/github/issues.go b/pkg/github/issues.go index dfb823e26b..1c27e15d82 100644 --- a/pkg/github/issues.go +++ b/pkg/github/issues.go @@ -946,6 +946,15 @@ func GetSubIssues(ctx context.Context, client *github.Client, deps ToolDependenc subIssues = filteredSubIssues } + for _, subIssue := range subIssues { + if subIssue.Title != nil { + subIssue.Title = github.Ptr(sanitize.Sanitize(*subIssue.Title)) + } + if subIssue.Body != nil { + subIssue.Body = github.Ptr(sanitize.Sanitize(*subIssue.Body)) + } + } + r, err := json.Marshal(subIssues) if err != nil { return nil, fmt.Errorf("failed to marshal response: %w", err) diff --git a/pkg/github/minimal_types.go b/pkg/github/minimal_types.go index e2bf8b684b..127e2e4b25 100644 --- a/pkg/github/minimal_types.go +++ b/pkg/github/minimal_types.go @@ -820,8 +820,10 @@ func convertToMinimalIssuesResponse(fragment IssueQueryFragment) MinimalIssuesRe func convertToMinimalIssueComment(comment *github.IssueComment) MinimalIssueComment { m := MinimalIssueComment{ - ID: comment.GetID(), - Body: comment.GetBody(), + ID: comment.GetID(), + // Bodies carry the same invisible-glyph / HTML injection surface as + // issue and PR bodies, which the read paths already sanitize. + Body: sanitize.Sanitize(comment.GetBody()), HTMLURL: comment.GetHTMLURL(), User: convertToMinimalUser(comment.GetUser()), AuthorAssociation: comment.GetAuthorAssociation(),