Skip to content

Dev-UI hardening leftovers: /wheels/info JSON metadata dump + core.cfm unvalidated format include #2974

Closed

Description

@bpamiri

Problem

Two dev-gated follow-ups promised in campaign PR bodies, never filed (coverage audit 2026-06-10):

  1. fix(view): redact secret-shaped settings on the /wheels/info HTML page #2909 deferral: the JSON branch of /wheels/info serializes the full getApplicationMetadata() (vendor/wheels/public/views/info.cfm:7) — datasource definitions and application config flow into the response wholesale, bypassing the per-setting redaction shipped for the settings list.
  2. fix(events): validate url.format to prevent error-template path traversal #2900 sibling: vendor/wheels/public/docs/core.cfm:77 does include "layouts/##format##.cfm" with unvalidated format — same traversal class $getRequestFormat was hardened against, on a dev-only page.

Impact

Both are development-environment-gated (post-#2903 fail-closed gate), so exploitation requires a dev-exposed instance — defense-in-depth, not urgent.

Suggested approach

(1) Route the JSON metadata through the same $isProtectedSetting()/$settingDisplayValue() single source of truth, or whitelist serialized keys. (2) Validate format against ^[A-Za-z0-9]+$ with html fallback, mirroring EventMethods.

Acceptance criteria

  • No secret-shaped values in the JSON branch output (spec).
  • Traversal vectors on core.cfm rejected (spec).

Source

Deferred-scope notes in PRs #2909/#2900; internal framework review 2026-06-09.

Activity

  1. wheels-bot commented on Jun 10, 2026

    @wheels-bot
    Contributor

    Wheels Bot — Triage

    Classified as bug.

    Suspected layer

    view — see .ai/wheels/views/ for canonical patterns. Both target files render under the dev-UI surface (vendor/wheels/public/), which doesn't have its own dedicated .ai/ doc; cross-engine compatibility guidance in .ai/wheels/cross-engine-compatibility.md and the existing $isProtectedSetting() / $settingDisplayValue() pattern in vendor/wheels/public/views/info.cfm are the relevant references.

    Fix sketch

    Two distinct changes in vendor/wheels/public/:

    1. views/info.cfm:154 — the JSON branch sets local.infoData.application.metadata = applicationMeta, serializing the full getApplicationMetadata() payload (including datasource definitions and application config) without passing through the per-setting redaction that the path/component/csrf/cors/settings loops already use. Fix shape: either route metadata fields through $isProtectedSetting() / $settingDisplayValue() like the surrounding loops, or replace the wholesale dump with an explicit whitelist of metadata keys safe for serialization (e.g. mappings, applicationName) — mirroring the structure that already exists for paths, components, etc.
    2. docs/core.cfm:77 — include "layouts/#request.wheels.params.format#.cfm" interpolates the unvalidated format request parameter directly into the include path. Fix shape: validate against ^[A-Za-z0-9]+$ with an html fallback before the include, matching the hardening pattern shipped for $getRequestFormat / EventMethods.

    Confidence: medium

    The report cites specific file:line references and a concrete fix shape, but there are two distinct fixes in one issue and the JSON-metadata fix requires a whitelist/redaction design choice (which metadata keys are safe) — propose-fix should split or sequence them and reuse the existing redaction predicates rather than introduce new ones.

    <!-- wheels-bot:triage:2974 -->
    <!-- wheels-bot:triage-class:bug -->
    <!-- wheels-bot:triage-confidence:medium -->

  2. wheels-bot commented on Jun 10, 2026

    @wheels-bot
    Contributor

    Wheels Bot — Fix proposed

    Draft PR: #2980

    Spec: vendor/wheels/tests/specs/security/DevUiHardeningLeftoversSpec.cfc — failing → passing (4 errors + 4 failures pre-fix, 0 / 0 after).

    Implementation:

    • vendor/wheels/Public.cfc — adds $resolveDocFormat() helper (^[A-Za-z0-9]+$ validator with html fallback, mirroring $getRequestFormat).
    • vendor/wheels/public/docs/core.cfm — routes request.wheels.params.format through $resolveDocFormat() before interpolating into the layouts/<format>.cfm include path.
    • vendor/wheels/public/views/info.cfm — JSON branch whitelists applicationMeta to { mappings } instead of dumping the full struct (datasource credentials no longer reach the response).

    Live /wheels/info?format=json verified: application.metadata now contains only { mappings: {...} }, no datasources block.

    A human review is required before merge. Reviewer A and Reviewer B will weigh in shortly. Doc updates (MDX guides, .ai/wheels/, CLAUDE.md) are handled separately by bot-update-docs.yml.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions