[code-scanning-fix] Fix workflow-graphql-id-unescaped: escape node IDs in GraphQL mutations#40757
Conversation
Wrap ownerId, projectId, and repositoryId with escapeGraphQLString() in the createProjectV2 and linkProjectV2ToRepository GraphQL mutations. Previously, title was consistently escaped but the node ID fields were not, creating a defense-in-depth gap. While GitHub API node IDs are opaque and currently safe, consistently applying escapeGraphQLString() ensures that if the values ever contain special characters the queries cannot be altered. Fixes code scanning alerts #627 and #628. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Great work from the Code Scanning Fixer workflow catching and addressing alerts #627 and #628 — wrapping One thing that would strengthen this before merge:
If you would like a hand, you can assign this prompt to your coding agent:
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR addresses code-scanning warnings for potential GraphQL injection by ensuring GitHub node IDs interpolated into GraphQL mutations are escaped consistently.
Changes:
- Escape
ownerIdwhen building thecreateProjectV2GraphQL mutation. - Escape
projectIdandrepoIdwhen building thelinkProjectV2ToRepositoryGraphQL mutation.
Show a summary per file
| File | Description |
|---|---|
| pkg/cli/project_command.go | Escapes node ID inputs embedded into GraphQL mutation strings to close a defense-in-depth injection gap. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 1/1 changed files
- Comments generated: 2
| } | ||
| } | ||
| }`, ownerId, escapeGraphQLString(title)) | ||
| }`, escapeGraphQLString(ownerId), escapeGraphQLString(title)) |
| } | ||
| } | ||
| }`, projectId, repoId) | ||
| }`, escapeGraphQLString(projectId), escapeGraphQLString(repoId)) |
Alert Numbers: #627, #628
Severity: Warning
Rule:
workflow-graphql-id-unescapedCWE: CWE-89
Vulnerability Description
In
pkg/cli/project_command.go, two GraphQL mutations were constructing query strings usingfmt.Sprintfwith unescaped node ID values:createProjectV2mutation (alert Add test agentic workflow for GitHub remote MCP #627, line 295):ownerIdwas interpolated directly, while the siblingtitleargument was correctly wrapped withescapeGraphQLString().linkProjectV2ToRepositorymutation (alert Add execution duration tracking to tool usage reporting for both Codex and Claude engines #628, line 368): BothprojectIdandrepositoryIdwere interpolated without escaping.This inconsistency creates a defense-in-depth gap. While GitHub API node IDs are opaque and currently safe, failing to escape them means that if the API ever returns a node ID containing special characters (e.g.,
",\), it could alter the structure of the GraphQL query (GraphQL injection, CWE-89).Location
pkg/cli/project_command.gocreateProjectfunction)linkProjectToRepofunction)Fix Applied
Wrapped the unescaped node ID arguments with the already-available
escapeGraphQLString()helper, making escaping consistent with thetitleargument and with the query construction on line 355 (which already usedescapeGraphQLStringforrepoOwnerandrepoName).Changes Made
ownerIdwithescapeGraphQLString()increateProjectV2mutationprojectIdwithescapeGraphQLString()inlinkProjectV2ToRepositorymutationrepoIdwithescapeGraphQLString()inlinkProjectV2ToRepositorymutationSecurity Best Practices Applied
escapeGraphQLString()escapeGraphQLString()helper is reused; no new dependencies introducedTesting Considerations
createProjectandlinkProjectToReposhould continue to passAutomated by: Code Scanning Fixer Workflow
Run ID: §27940907624
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
proxy.golang.orgSee Network Configuration for more information.