Skip to content

HYPERFLEET-1376 - fix: avoid leaking internal type names in validation errors#306

Open
mliptak0 wants to merge 4 commits into
openshift-hyperfleet:mainfrom
mliptak0:HYPERFLEET-1376
Open

HYPERFLEET-1376 - fix: avoid leaking internal type names in validation errors#306
mliptak0 wants to merge 4 commits into
openshift-hyperfleet:mainfrom
mliptak0:HYPERFLEET-1376

Conversation

@mliptak0

@mliptak0 mliptak0 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

What

  • Stopped leaking internal Go struct/package names (e.g. ResourcePatchRequest, openapi.ConditionRequest) in 400 error messages when a request sends the wrong JSON type for labels or conditions.
  • Fixed PATCH requests that only send references (no labels/spec) — these were wrongly rejected with "at least one field must be provided for update".

Why

API callers shouldn't see our internal Go type names in error messages, and a references-only PATCH is a perfectly valid update that shouldn't be blocked.

Test Plan

  • Unit tests added/updated
  • make test-all passes
  • make lint passes
  • Helm chart changes validated with make test-helm (if applicable)
  • Deployed to a development cluster and verified (if Helm/config changes)
  • E2E tests passed (if cross-component or major changes)

@openshift-ci
openshift-ci Bot requested review from aredenba-rh and mbrudnoy July 21, 2026 10:47
@openshift-ci

openshift-ci Bot commented Jul 21, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign aredenba-rh for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

JSON unmarshalling type mismatches now produce structured validation errors naming the affected field and expected JSON kind across shared, force-delete, and create-with-no-content handlers. Other decoding failures retain existing fallback behavior. Patch validation now accepts References alongside Spec and Labels, with coverage for references-only patches and clean type-mismatch responses.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: aredenba-rh, mbrudnoy, kuudori, tirthct

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (10 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Sec-02: Secrets In Log Output ✅ Passed No non-test/example log or print statements contained token/password/credential/secret; scan found 0 hits (CWE-532).
No Hardcoded Secrets ✅ Passed No hardcoded credentials found in the changed files; only test fixtures and validation strings. No apiKey/secret/token/password literals, embedded creds, or long base64 blobs (CWE-798/CWE-259).
No Weak Cryptography ✅ Passed No CWE-327/328 issues: touched code only adds JSON validation and tests; no md5/des/rc4/SHA1-for-security, ECB, custom crypto, or secret comparisons found.
No Injection Vectors ✅ Passed No CWE-89/78/79/502 sinks were added in the changed non-test code; only error normalization and validation logic changed.
No Privileged Containers ✅ Passed Only Go test files changed; no manifests/templates/Dockerfiles were modified, and no privileged settings were present. CWE-250 not introduced.
No Pii Or Sensitive Data In Logs ✅ Passed PASS: No new slog/logr/zap/fmt.Print logging was added; changed error text is field/type-only, not PII or raw bodies. CWE-532 not implicated.
Title check ✅ Passed Matches the main change: sanitizing validation errors to avoid internal type-name leakage (CWE-200).
Description check ✅ Passed Describes the same fixes: cleaner 400 errors and allowing references-only PATCH requests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/handlers/framework.go`:
- Around line 159-172: Update describeJSONKind to explicitly map all numeric
reflect.Kind values to "a number", and handle unsupported kinds such as
reflect.Ptr, reflect.Interface, and reflect.Invalid with a safe non-numeric
fallback. Remove the unjustified catch-all behavior so unhandled enum values
cannot produce factually incorrect API errors.

In `@pkg/handlers/validation.go`:
- Around line 253-261: Guard the reflection setup before dereferencing in the
validation flow: validate that reflect.ValueOf(i) is valid, is a pointer or
interface, and is non-nil before calling Elem, returning the existing validation
error path for invalid inputs. Before each IsNil call for Spec, Labels, and
References, only call it for nil-capable kinds (pointer, slice, map, channel,
func, or interface); treat other valid concrete fields as present without
panicking.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e5824cff-bef1-4940-87e6-d39a49bdbe4d

📥 Commits

Reviewing files that changed from the base of the PR and between 5aefe87 and 3a2f3c5.

📒 Files selected for processing (2)
  • pkg/handlers/framework.go
  • pkg/handlers/validation.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

Comment thread pkg/handlers/framework.go
Comment thread pkg/handlers/validation.go
@hyperfleet-ci-bot

hyperfleet-ci-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Risk Score: 0 — risk/low

Signal Detail Points
PR size 200 lines +0
Sensitive paths none +0
Test coverage Tests cover changed packages +0

Computed by hyperfleet-risk-scorer

…n errors

Co-authored-by: Cursor <cursoragent@cursor.com>
@mliptak0 mliptak0 changed the title HYPERFLEET-1376 - fix: Clean up internal Go type/package leaks in JSON decode + PATCH validation errors HYPERFLEET-1376 - fix: avoid leaking internal type names in validation errors Jul 21, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
@mliptak0

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

mliptak0 and others added 2 commits July 22, 2026 11:37
…requests

handleForceDelete (POST /{plural}/{id}/force-delete) was still leaking
the Go struct name in its error detail (e.g. "cannot unmarshal number
into Go struct field ForceDeleteRequest.reason of type string") because
it didn't route decode errors through cleanTypeMismatchError like the
other three decode paths. Applying the same check there closes the last
unsanitized endpoint.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…d references-only patch fixes

Re-adds the regression tests for findings 1-4 (labels/conditions type
mismatch clean messages, references-only PATCH) that were dropped when
the framework.go/validation.go fixes were rewritten in 21a802a and
0576411. Assertions updated to match the current cleanTypeMismatchError
message format ("field '<name>' must be <kind>").

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown

@mliptak0: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/validate-commits 364f1cb link true /test validate-commits

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/handlers/resource_handler_test.go`:
- Around line 279-297: Strengthen the “Success - references only” test’s Patch
expectation by capturing or structurally matching the *api.ResourcePatch
argument instead of accepting any value. Assert that References preserves the
parents entry with kind “Cluster” and ID “cluster-1”, while retaining the
existing successful response and status assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 003292cb-bbd6-4542-8473-1e2155e8f961

📥 Commits

Reviewing files that changed from the base of the PR and between 0576411 and 364f1cb.

📒 Files selected for processing (4)
  • pkg/handlers/framework.go
  • pkg/handlers/resource_handler_test.go
  • pkg/handlers/resource_status_handler_test.go
  • pkg/handlers/validation_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

Comment on lines +279 to +297
{
// References-only patch must be accepted, not rejected as "no field provided" — HYPERFLEET-1376 finding 8.
name: "Success - references only",
id: "ch-123",
body: `{"references":{"parents":[{"kind":"Cluster","id":"cluster-1"}]}}`,
setupMock: func(mock *services.MockResourceService) {
mock.EXPECT().Patch(gomock.Any(), "Channel", "ch-123", gomock.AssignableToTypeOf(&api.ResourcePatch{})).
Return(&api.Resource{
Meta: api.Meta{ID: "ch-123", CreatedTime: now, UpdatedTime: now},
Kind: "Channel",
Name: "stable",
Spec: datatypes.JSON(`{"is_default":false}`),
Generation: 2,
CreatedBy: "user@test.com",
UpdatedBy: "user@test.com",
}, nil)
},
expectedStatusCode: http.StatusOK,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Assert the references payload passed to Patch.

Line 285 accepts any *api.ResourcePatch, so this passes if decoding or handler wiring drops References before the service call. Capture or match the argument and verify the parents reference, kind, and ID; Sentinel relies on this map/array contract being preserved.

As per path instructions, “New exported functions and critical logic paths SHOULD have tests.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/handlers/resource_handler_test.go` around lines 279 - 297, Strengthen the
“Success - references only” test’s Patch expectation by capturing or
structurally matching the *api.ResourcePatch argument instead of accepting any
value. Assert that References preserves the parents entry with kind “Cluster”
and ID “cluster-1”, while retaining the existing successful response and status
assertions.

Sources: Path instructions, Linked repositories

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant