Skip to content

fix(orchestrator): Address CVE-2026-3118 (#2597)#2737

Merged
lholmquist merged 1 commit intoworkspace/orchestratorfrom
1.9-cve-backport-lholmquist
Apr 9, 2026
Merged

fix(orchestrator): Address CVE-2026-3118 (#2597)#2737
lholmquist merged 1 commit intoworkspace/orchestratorfrom
1.9-cve-backport-lholmquist

Conversation

@lholmquist
Copy link
Copy Markdown
Member

cherry-pick for PR #2597

  • 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

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

* 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
@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Address CVE-2026-3118 by implementing GraphQL query variables

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Migrate GraphQL queries to use query variables instead of string interpolation
  - Filters, pagination, and queries now use parameterized variables
  - Prevents GraphQL injection vulnerabilities (CVE-2026-3118)
• Refactor filter builder to return structured FilterClause objects
  - Separates filter clause strings from variable definitions
  - Enables proper variable substitution in GraphQL queries
• Update @urql/core dependency from 4.1.4 to 6.0.1
• Restructure query builder to support query variables for pagination and ordering
Diagram
flowchart LR
  A["Filter/Query Builders"] -->|"Return FilterClause"| B["FilterClause Object"]
  B -->|"Contains clause + variables"| C["Query Builder"]
  C -->|"Injects variables"| D["GraphQL Query with Parameters"]
  D -->|"Passes to client"| E["URQL Client 6.0.1"]
  E -->|"Executes safely"| F["Data Index Service"]
Loading

Grey Divider

File Changes

1. workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts Security enhancement +105/-25

Refactor filter builder to use query variables

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts


2. workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilders.test.ts 🧪 Tests +156/-46

Update tests for parameterized filter variables

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilders.test.ts


3. workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/queryBuilder.ts ✨ Enhancement +63/-25

Implement query variables for pagination and filters

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/queryBuilder.ts


View more (7)
4. workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/queryBuilder.test.ts 🧪 Tests +7/-18

Update query builder tests for variables

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/queryBuilder.test.ts


5. workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.ts ✨ Enhancement +102/-22

Integrate query variables into data fetching

workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.ts


6. workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.test.ts 🧪 Tests +197/-93

Update service tests for variable-based queries

workspaces/orchestrator/plugins/orchestrator-backend/src/service/DataIndexService.test.ts


7. workspaces/orchestrator/plugins/orchestrator-backend/src/types/filterClause.ts New types +26/-0

Define FilterClause and FilterClauseVariable types

workspaces/orchestrator/plugins/orchestrator-backend/src/types/filterClause.ts


8. workspaces/orchestrator/plugins/orchestrator-backend/src/types/pagination.ts ✨ Enhancement +7/-1

Add PaginationQueryVariable interface

workspaces/orchestrator/plugins/orchestrator-backend/src/types/pagination.ts


9. workspaces/orchestrator/plugins/orchestrator-backend/package.json Dependencies +1/-1

Upgrade @urql/core to 6.0.1

workspaces/orchestrator/plugins/orchestrator-backend/package.json


10. workspaces/orchestrator/.changeset/five-meals-cover.md 📝 Documentation +6/-0

Document CVE fix and query variable refactoring

workspaces/orchestrator/.changeset/five-meals-cover.md


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge Bot commented Apr 9, 2026

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1)

Grey Divider


Action required

1. Enum typed as String 🐞
Description
handleBinaryOperator() declares scalar (non-array) filter variables as type String even when
isEnumFilter() marks the field (e.g. state) as an enum, which can make the generated GraphQL
query invalid due to variable type mismatch. As a result, filtering ProcessInstance.state with
EQ can fail at query validation/execution time while IN works (since it uses
[ProcessInstanceState!]).
Code

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[R195-216]

+  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 = {
Evidence
The backend explicitly treats state as an enum (isEnumFilter()), and the array path uses an enum
variable type ([ProcessInstanceState!]), but the scalar path hard-codes paramType = 'String'.
This inconsistency means enum scalar filters will be emitted with the wrong GraphQL variable type.

workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[164-174]
workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[183-229]
workspaces/orchestrator/plugins/orchestrator-backend/src/service/fixtures/mockProcessInstanceArgumentsData.ts[115-122]
workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilders.test.ts[707-721]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`handleBinaryOperator()` generates GraphQL variable declarations for filter values. For enum fields (currently `ProcessInstance.state`), the array path correctly uses an enum type (`[ProcessInstanceState!]`), but the scalar path always uses `String`, which can break GraphQL validation/execution.

### Issue Context
- `isEnumFilter()` marks `state` as an enum field.
- Array enum filters use `[ProcessInstanceState!]`.
- Scalar enum filters currently use `String`.

### Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[164-229]

### What to change
- In the scalar (`else`) branch inside `handleBinaryOperator()`, set `paramType` based on `isEnumFilter(binaryFilter.field, type)` (e.g., `ProcessInstanceState` for `state`) instead of hard-coding `String`.
- (Optional hardening) Centralize enum-type mapping so future enum fields don’t require scattered hard-coded types.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 9, 2026

Comment on lines +195 to +216
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 = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Enum typed as string 🐞 Bug ≡ Correctness

handleBinaryOperator() declares scalar (non-array) filter variables as type String even when
isEnumFilter() marks the field (e.g. state) as an enum, which can make the generated GraphQL
query invalid due to variable type mismatch. As a result, filtering ProcessInstance.state with
EQ can fail at query validation/execution time while IN works (since it uses
[ProcessInstanceState!]).
Agent Prompt
### Issue description
`handleBinaryOperator()` generates GraphQL variable declarations for filter values. For enum fields (currently `ProcessInstance.state`), the array path correctly uses an enum type (`[ProcessInstanceState!]`), but the scalar path always uses `String`, which can break GraphQL validation/execution.

### Issue Context
- `isEnumFilter()` marks `state` as an enum field.
- Array enum filters use `[ProcessInstanceState!]`.
- Scalar enum filters currently use `String`.

### Fix Focus Areas
- workspaces/orchestrator/plugins/orchestrator-backend/src/helpers/filterBuilder.ts[164-229]

### What to change
- In the scalar (`else`) branch inside `handleBinaryOperator()`, set `paramType` based on `isEnumFilter(binaryFilter.field, type)` (e.g., `ProcessInstanceState` for `state`) instead of hard-coding `String`.
- (Optional hardening) Centralize enum-type mapping so future enum fields don’t require scattered hard-coded types.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@lholmquist lholmquist merged commit 13159d3 into workspace/orchestrator Apr 9, 2026
9 checks passed
@lholmquist lholmquist deleted the 1.9-cve-backport-lholmquist branch April 17, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant