fix(orchestrator): Address CVE-2026-3118 (#2597) (#2727)#2730
Conversation
* fix: Update grapql client * Filters, pagination and queries now use query variables fixes CVE-2026-3118 and relates to JIRA https://redhat.atlassian.net/browse/RHIDP-12388 and https://redhat.atlassian.net/browse/RHIDP-12583
Review Summary by QodoFix CVE-2026-3118 by implementing parameterized GraphQL queries with variables
WalkthroughsDescription• Migrate GraphQL queries to use query variables instead of string interpolation • Update @urql/core dependency from 4.1.4 to 6.0.1 to address CVE-2026-3118 • Refactor filter builder to return FilterClause objects with separated clause and variables • Implement parameterized queries for filters, pagination, and orderBy operations • Update test cases to validate variable substitution and formatted values Diagramflowchart LR
A["String Interpolation<br/>GraphQL Queries"] -->|"Refactor to use<br/>Query Variables"| B["Parameterized<br/>GraphQL Queries"]
C["Filter Builder<br/>Returns String"] -->|"Return FilterClause<br/>with Variables"| D["FilterClause Object<br/>clause + variables"]
E["@urql/core 4.1.4<br/>CVE-2026-3118"] -->|"Update to 6.0.1"| F["@urql/core 6.0.1<br/>Secure"]
D -->|"Pass to Query Builder"| B
B -->|"Execute with<br/>Parameter Variables"| G["Secure GraphQL<br/>Execution"]
File Changes1. workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts
|
Code Review by Qodo
|
|
| ): FilterClause { | ||
| if (!filters) { | ||
| return ''; | ||
| return {} as FilterClause; | ||
| } |
There was a problem hiding this comment.
1. Empty filterclause is truthy 🐞 Bug ≡ Correctness
buildFilterCondition returns {} cast as FilterClause when filters is missing, producing a
truthy object with undefined clause/clauseVariable. Callers like DataIndexService treat this as
present and can build GraphQL where strings containing {undefined} and/or pass malformed filter
variables downstream.
Agent Prompt
### Issue description
`buildFilterCondition()` (and `handleLogicalFilter()` when `operator` is missing) returns `{} as FilterClause`. This creates a truthy value with missing fields, which then gets treated as a real filter and can render `where` fragments like `{undefined}`.
### Issue Context
Callers (e.g., `DataIndexService`) use `if (filterCondition)` to decide whether to include the filter, and then interpolate `filterCondition.clause`.
### Fix approach
Prefer one of these (choose consistently across the codebase):
1) Change return type to `FilterClause | undefined` and return `undefined` for “no filter / invalid filter”, OR
2) Return a structurally valid empty clause: `{ clause: '', clauseVariable: [] }` and update call sites to check `filterCondition.clause` (non-empty) rather than object truthiness.
### Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[76-92]
- workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[231-247]
- workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.ts[222-277]
- workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.ts[279-323]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| let formattedValue: any; | ||
| let paramType: string; | ||
| if (Array.isArray(binaryFilter.value)) { | ||
| formattedValue = binaryFilter.value.map(v => | ||
| formatValue(binaryFilter.field, v, fieldDef, type), | ||
| ); | ||
| paramType = isEnumFilter(binaryFilter.field, type) | ||
| ? '[ProcessInstanceState!]' | ||
| : '[String!]'; | ||
| } else { | ||
| formattedValue = formatValue( | ||
| binaryFilter.field, | ||
| binaryFilter.value, | ||
| fieldDef, | ||
| type, | ||
| ); | ||
| paramType = 'String'; | ||
| } | ||
|
|
||
| const clauseVariableName = `clauseVariable${nonSecureRandomAlphaNumeric()}`; | ||
| const clause = `${binaryFilter.field}: {${getGraphQLOperator(binaryFilter.operator)}: $${clauseVariableName}}`; | ||
| const filterClauseVariable: FilterClauseVariable = { |
There was a problem hiding this comment.
2. Enum variable type mismatch 🐞 Bug ≡ Correctness
handleBinaryOperator sets the GraphQL variable type for scalar enum filters (e.g. state EQ ...) to String while using [ProcessInstanceState!] for array enum filters. This inconsistency can cause GraphQL validation errors if the schema expects ProcessInstanceState for equal on state.
Agent Prompt
### Issue description
Enum filters for `state` use inconsistent GraphQL variable types: array values use `[ProcessInstanceState!]` but scalar values use `String`. This can break queries depending on the GraphQL schema.
### Issue Context
`isEnumFilter()` identifies `state` as enum-like, and the code already hardcodes `ProcessInstanceState` for the list case.
### Fix approach
Update the scalar branch in `handleBinaryOperator()` so that when `isEnumFilter(binaryFilter.field, type)` is true, `paramType` is the matching enum type (e.g., `ProcessInstanceState`), not `String`.
Optionally (more robust): derive the correct GraphQL input type name from introspection rather than hardcoding `ProcessInstanceState`.
### Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[164-229]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



fix: Update grapql client
Filters, pagination and queries now use query variables
fixes CVE-2026-3118 and relates to JIRA https://redhat.atlassian.net/browse/RHIDP-12388 and https://redhat.atlassian.net/browse/RHIDP-12583
Hey, I just made a Pull Request!
✔️ Checklist