Skip to content

chore(deps-dev): update dependency @hey-api/openapi-ts to v0.97.3 [security] - #1137

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-hey-api-openapi-ts-vulnerability
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-hey-api-openapi-ts-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@hey-api/openapi-ts (source) 0.95.00.97.3 age confidence

@​hey-api/openapi-ts's buildClientParams template: prototype chain substitution via unknown $<slot>___proto__ key

CVE-2026-48819 / GHSA-hhx9-57xq-r5rw

More information

Details

Summary

dist/clients/core/params.ts in @hey-api/openapi-ts ships a runtime template that is copied verbatim into every generated SDK as params.gen.ts. When a caller passes an object argument containing an unknown key starting with a slot prefix ($body_, $headers_, $path_, $query_), the function strips the prefix and writes the remainder directly to that slot without validation. The key "$query___proto__" causes the returned params.query object to have its prototype chain substituted with attacker-controlled data. The issue is present in all versions through at least 0.97.2.

Details

The vulnerable branch in dist/clients/core/params.ts:

const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix))
if (extra) {
  const [prefix, slot] = extra
  ;(params[slot] as Record<string, unknown>)[key.slice(prefix.length)] = value
}

This branch runs for any key that (1) is not registered in the field map and (2) starts with one of the four slot prefixes. When a caller passes "$query___proto__" as an extra key alongside a legitimate field, the key is not in the field map, key.startsWith("$query_") is true, and key.slice(7) produces "__proto__". The bracket-write params["query"]["__proto__"] = value invokes the __proto__ setter, which calls Object.setPrototypeOf(params.query, value).

Reachability. Every generated endpoint method that accepts an object argument passes it through buildClientParams. If the application forwards user-supplied request parameters to a generated client method — a common pattern in proxy servers, BFF layers, and API gateways — an attacker can include "$query___proto__" alongside a legitimate field (e.g. "q"). The legitimate field ensures stripEmptySlots does not remove the affected slot (it has at least one own key), so the poisoned params.query object is returned to the caller.

Concrete field config that hey-api generates for a GET endpoint with one query param q:

// generated by hey-api for: GET /search?q=<string>
buildClientParams([parameters], [{ args: [{ in: "query", key: "q" }] }])

A request { q: "hello", "$query___proto__": { isAdmin: true } } reaches this call with "q" going to the field map branch and "$query___proto__" falling through to extraPrefixes.

PoC
npm install @hey-api/openapi-ts@0.97.2
cp node_modules/@hey-api/openapi-ts/dist/clients/core/params.ts ./params.ts
npx tsx poc.ts

##### or: docker build -t heyapi-poc . && docker run --rm heyapi-poc

poc.ts:

import { buildClientParams } from "./params.ts";

// Generated fields config for GET /search?q=<string>
const generatedFields = [{ args: [{ in: "query" as const, key: "q" }] }];

// Attacker request: legitimate "q" plus injected "$query___proto__"
const result = buildClientParams(
  [{ q: "hello", "$query___proto__": { isAdmin: true } }],
  generatedFields
);

const q = result.query as any;
console.log(q.q);                           // "hello" — own property, normal
console.log(q.isAdmin);                     // true — inherited via prototype chain
console.log(Object.keys(q));               // ["q"] — own keys only
for (const k in result.query) console.log(k); // "q", "isAdmin"

Expected output:

[CONFIRMED] buildClientParams prototype substitution via $query___proto__ key
  Scenario: GET /search with fields [{ in:'query', key:'q' }]
  Attacker request: { q: 'hello', '$query___proto__': { isAdmin: true } }

  result.query.q         = hello
  result.query.isAdmin   = true  ← inherited, NOT own
  Object.keys(q)         = [ 'q' ]
  for..in keys           = q, isAdmin
  Object.getPrototypeOf  = {"isAdmin":true}

No sentinel key is needed. The legitimate field "q" keeps params.query alive through stripEmptySlots.
reproduce.zip

Impact

The returned params.query object has its prototype chain substituted with the attacker-supplied value. Any downstream code that iterates it with for..in (e.g., when serializing query parameters for an outgoing HTTP request) will enumerate the injected keys alongside legitimate ones. Applications that check inherited properties on the params object for routing or authorization decisions are also affected.

Global Object.prototype is not modified — impact is limited to the returned slot object and its consumers.

Every npm package generated by @hey-api/openapi-ts carries this template. Downstream packages include @opencode-ai/sdk, @trigger.dev/sdk, and others. A fix in the template propagates to all of them on regeneration.

Severity

  • CVSS Score: 4.8 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

hey-api/hey-api (@​hey-api/openapi-ts)

v0.97.3

Patch Changes
Updated Dependencies:

v0.97.2

Patch Changes
Updated Dependencies:

v0.97.1

Patch Changes
Updated Dependencies:

v0.97.0

Minor Changes
Changed runtimeConfigPath behavior

This was a known, long-standing issue confusing first-time users. Before, defining client runtimeConfigPath value would paste it verbatim to the generated output. This release changes the behavior to resolve relative to the current working directory the same way output path works.

Changed Ky client behavior

The Ky client was updated to be more intuitive. Some Ky options now need to be passed via the kyOptions field and you need to pass undefined to unset an option.

Patch Changes
Updated Dependencies:

v0.96.1

Patch Changes
Updated Dependencies:

v0.96.0

Minor Changes
Patch Changes
Updated Dependencies:

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.


Note

Low Risk
Single devDependency version bump with no application runtime or generated client changes in the PR; residual risk is limited to future codegen output differing until openapi-ts is re-run.

Overview
Bumps the devDependency @hey-api/openapi-ts from 0.95.0 to 0.97.3 in package.json, addressing CVE-2026-48819 (prototype-chain substitution via $<slot>___proto__ keys in the generated buildClientParams template).

This only changes the OpenAPI codegen tool version used by npm run openapi-ts / openapi-ts:local to regenerate src/client/; no generated client files are updated in this diff. After merge, consider re-running codegen so checked-in SDK output picks up the fixed runtime template.

Reviewed by Cursor Bugbot for commit 08cf487. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Metric Current Previous Change Status
Total (gzip) 278.9 kB 278.9 kB +2 B (+0.0%) 🔴
Total (raw) 738.25 kB 738.25 kB 0 B (0%) 🟢
CSS (gzip) 21.79 kB 21.79 kB 0 B (0%) 🟢
CSS (raw) 113.29 kB 113.29 kB 0 B (0%) 🟢

Size Limits

  • ✅ Total gzipped: 278.9 kB / 350 kB (79.7%)
  • ✅ Total raw: 738.25 kB / 850 kB (86.9%)
  • ✅ CSS gzipped: 21.79 kB / 25 kB (87.1%)

Largest Files (Top 5)

  1. chunk-SRLBVFNQ.js - 12.94 kB (0 B (0%))
  2. styles.css - 10.89 kB (0 B (0%))
  3. index.css - 10.89 kB (0 B (0%))
  4. index.js - 7 kB (0 B (0%))
  5. chunk-DAUDKN32.js - 6.58 kB (0 B (0%))
View All Files (458 total)
File Size (gzip) Change
chunk-SRLBVFNQ.js 12.94 kB 0 B (0%)
styles.css 10.89 kB 0 B (0%)
index.css 10.89 kB 0 B (0%)
index.js 7 kB 0 B (0%)
chunk-DAUDKN32.js 6.58 kB 0 B (0%)
chunk-GO6XCLPF.js 6.44 kB 0 B (0%)
chunk-SMCLTRJW.js 5.84 kB 0 B (0%)
chunk-C4HFMTSB.js 5.33 kB 0 B (0%)
chunk-26HC7ESE.js 4.7 kB 0 B (0%)
chunk-H4JKYSQC.js 4.35 kB 0 B (0%)

✅ Bundle size check passed

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

📊 Coverage Report

⚪ Coverage unchanged

Metric Current Previous Change Status
Lines 86.16% 86.16% 0%
Statements 85.74% 85.74% 0%
Functions 84.68% 84.68% 0%
Branches 77.42% 77.42% 0%

Detailed Breakdown

Lines Coverage
  • Covered: 4712 / 5469
  • Coverage: 86.16%
  • Change: 0% (0 lines)
Statements Coverage
  • Covered: 4797 / 5595
  • Coverage: 85.74%
  • Change: 0% (0 statements)
Functions Coverage
  • Covered: 1255 / 1482
  • Coverage: 84.68%
  • Change: 0% (0 functions)
Branches Coverage
  • Covered: 2904 / 3751
  • Coverage: 77.42%
  • Change: 0% (0 branches)

✅ Coverage check passed

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Deploy preview for adp-cost-calculator ready!

Project:adp-cost-calculator
Status: ✅  Deploy successful!
Preview URL:https://adp-cost-calculator-bbumys8sk-remotecom.vercel.app
Latest Commit:08cf487

Deployed with vercel-action

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Deploy preview for remote-flows ready!

Project:remote-flows
Status: ✅  Deploy successful!
Preview URL:https://remote-flows-6bbdnrikb-remotecom.vercel.app
Latest Commit:08cf487

Deployed with vercel-action

@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 2 times, most recently from f0df58b to b74704d Compare July 16, 2026 19:34
@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch from b74704d to 1196698 Compare July 21, 2026 01:55
Comment thread package.json
"devDependencies": {
"@arethetypeswrong/cli": "0.18.3",
"@hey-api/openapi-ts": "0.95.0",
"@hey-api/openapi-ts": "0.97.3",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Client codegen not regenerated

Medium Severity

This change only bumps @hey-api/openapi-ts to 0.97.3; it does not regenerate src/client. The shipped buildClientParams in params.gen.ts still assigns extra $query_ / similar keys without blocking __proto__, so the CVE-2026-48819 fix is not in the built client until npm run openapi-ts is run and committed.

Fix in Cursor Fix in Web

Triggered by project rule: Code Review Guidelines

Reviewed by Cursor Bugbot for commit 1196698. Configure here.

@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 2 times, most recently from 93ad642 to c45b248 Compare July 30, 2026 13:48
@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 2 times, most recently from 0bdf402 to cf5bc43 Compare August 4, 2026 15:21

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread package-lock.json Outdated
},
"engines": {
"node": ">=20.19.0"
"node": ">=22.13.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Node engine requirement mismatch

Low Severity

@hey-api/openapi-ts 0.97.3 requires Node >=22.13.0, but this repo still documents and declares Node >=20. Developers on Node 20–22.12 who follow the docs will fail when running npm run openapi-ts.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cf5bc43. Configure here.

@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 2 times, most recently from 6af910d to 5bdad09 Compare August 14, 2026 22:51
@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 2 times, most recently from c1a0cf8 to 34e5d01 Compare September 2, 2026 16:54
@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 4 times, most recently from 0063eb6 to e509cb3 Compare September 9, 2026 12:51
@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch 3 times, most recently from 4997c3f to 17328b9 Compare September 15, 2026 09:04

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread package.json
"@arethetypeswrong/cli": "0.18.5",
"@faker-js/faker": "^10.6.0",
"@hey-api/openapi-ts": "0.95.0",
"@hey-api/openapi-ts": "0.97.3",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Generator now requires Node 22

Low Severity

@hey-api/openapi-ts 0.97.3 (via the 0.96.0 breaking change) requires Node >=22.13.0, but this package still declares engines.node as >=20 and documents Node 20 as the minimum. npm run openapi-ts can fail for developers on the currently supported Node 20 toolchain.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 17328b9. Configure here.

@renovate
renovate Bot force-pushed the renovate/npm-hey-api-openapi-ts-vulnerability branch from 17328b9 to 08cf487 Compare September 16, 2026 15:58
@renovate

renovate Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: package-lock.json
npm warn config optional Use `--omit=optional` to exclude optional dependencies, or
npm warn config `--include=optional` to include them.
npm warn config
npm warn config       Default value does install optional deps unless otherwise omitted.
npm warn Unknown env config "store". This will error in a future major version of npm. See `npm help npmrc` for supported config options.
npm error code EALLOWREMOTE
npm error Fetching packages of type "remote" have been disabled
npm error Refusing to fetch "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz"
npm error A complete log of this run can be found in: /runner/cache/others/npm/_logs/2026-09-16T15_58_26_017Z-debug-0.log

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 08cf487. Configure here.

Comment thread package.json
"@arethetypeswrong/cli": "0.18.5",
"@faker-js/faker": "^10.6.0",
"@hey-api/openapi-ts": "0.95.0",
"@hey-api/openapi-ts": "0.97.3",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lockfile out of sync with package.json

High Severity

package.json pins @hey-api/openapi-ts to 0.97.3, but package-lock.json still resolves 0.95.0. PR and main CI both run npm ci, which fails when those files disagree, so this bump cannot install or land.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 08cf487. Configure here.

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.

0 participants