Skip to content

fix(data-inspector): block prototype-chain writes - #324

Merged
antfu merged 1 commit into
mainfrom
fix/data-inspector-prototype-writes
Sep 1, 2026
Merged

fix(data-inspector): block prototype-chain writes#324
antfu merged 1 commit into
mainfrom
fix/data-inspector-prototype-writes

Conversation

@antfubot

@antfubot antfubot commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements plan 005-block-data-inspector-prototype-writes.md. Data Inspector's write engine re-descended object paths through inherited properties and assigned caller-selected keys directly, so a write request could reach or replace a shared prototype. This closes that off while preserving Map key semantics.

  • navigate() now returns undefined for a plain-object key that isn't an own property, instead of following the prototype chain (Map .get behavior is unchanged).
  • Plain-object set/add/rename destinations reject __proto__, prototype, and constructor.
  • add and rename create the destination as an own data property via Object.defineProperty, so an inherited setter can never fire.
  • set now requires Object.hasOwn before reading/assigning an existing property, closing the same hole for property names that exist only on the prototype chain.
  • Map keys are untouched — a Map may still use these strings as ordinary data keys, and non-Map array/Set operations are unaffected.

Scope

  • plugins/data-inspector/src/engine/normalize.ts
  • plugins/data-inspector/src/engine/write.ts
  • plugins/data-inspector/test/write.test.ts (new regression coverage: rejected prototype-sensitive keys on set/add/rename, inherited-property paths reporting PathNotFound, an inherited-setter fixture proving add/rename never invoke it, and a positive Map test)
  • plans/README.md (marks plan 005 done)

Verification

  • pnpm exec vitest run plugins/data-inspector/test/write.test.ts plugins/data-inspector/test/engine.test.ts — 53 passed
  • pnpm --filter @devframes/plugin-data-inspector typecheck — exit 0
  • pnpm --filter @devframes/plugin-data-inspector build / test — pass
  • pnpm lint — pass
  • Full-repo pnpm knip/pnpm test/pnpm typecheck/pnpm build hit pre-existing, unrelated environment issues in this sandbox (a permission-broken plugins/git/assets-pkg/dist artifact, and several packages whose dist/ isn't built) — confirmed identical on HEAD~1 via git stash, so unaffected by this change. A full repo-wide pnpm exec vitest run shows the same unrelated pre-existing failures (dist-artifact-dependent exports.test.ts/dev-server suites for other plugins); the data-inspector suite is unaffected.

Created with the help of an agent (opencode).

Restrict Data Inspector's write engine to own-property traversal and
mutation so a write path can no longer reach or replace a shared
prototype:

- navigate() now returns undefined for a plain-object key that isn't
  an own property, instead of following the prototype chain.
- Plain-object set/add/rename destinations reject __proto__,
  prototype, and constructor.
- add and rename create the destination as an own data property via
  Object.defineProperty, so an inherited setter can never fire.
- set now requires Object.hasOwn before reading/assigning, closing the
  same hole for existing-but-inherited property names.

Map key semantics are untouched — a Map may still use these strings as
ordinary data keys.
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
devframe Ready Ready Preview Sep 1, 2026 6:13am UTC

@antfu
antfu merged commit 740fa95 into main Sep 1, 2026
13 checks passed
@antfu
antfu deleted the fix/data-inspector-prototype-writes branch September 1, 2026 06:26
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.

2 participants