fix(unset): guard against prototype keyword path traversal - #13560
Merged
bluebill1049 merged 1 commit intoJun 30, 2026
Merged
Conversation
…k-form#13559) The unset() utility traverses nested paths via an internal baseGet() helper without checking for prototype-pollution keywords (__proto__, constructor, prototype). set.ts already contains this guard, but unset.ts did not have an equivalent. As a result, a path like '__proto__.foo' would cause baseGet to walk into Object.prototype, and the subsequent delete would remove a property from the prototype itself. Fix: after computing the paths array, bail out early (no-op) if any segment is in PROTOTYPE_KEYWORDS, matching the existing protection in set.ts. Fixes react-hook-form#13559
bluebill1049
approved these changes
Jun 30, 2026
bluebill1049
approved these changes
Jun 30, 2026
KATT
added a commit
to KATT/react-hook-form
that referenced
this pull request
Jul 3, 2026
…bmitting-cypress-jest * origin/master: 🐞 fix(flatten): preserve Date values as leaf nodes (react-hook-form#13566) Revert "docs: fix grammar in demo descriptions (react-hook-form#13565)" (react-hook-form#13568) Revert "test: remove duplicate UseFieldArray slug (react-hook-form#13564)" (react-hook-form#13567) test: remove duplicate UseFieldArray slug (react-hook-form#13564) docs: fix grammar in demo descriptions (react-hook-form#13565) 🐞 fix(useController): reflect cleared parent object in controlled fields (react-hook-form#13550) (react-hook-form#13553) 📖 docs: replace dead /api links with /docs in locale READMEs (react-hook-form#13561) 🐛 fix(unset): guard against prototype keyword path traversal (react-hook-form#13559) (react-hook-form#13560) 📖 docs: replace retired /jp, /pt, /zh subdomain links in locale READMEs (react-hook-form#13556)
KATT
added a commit
to KATT/react-hook-form
that referenced
this pull request
Jul 3, 2026
…ssubmitting * repro/activity-issubmitting-vitest: 🐞 fix(flatten): preserve Date values as leaf nodes (react-hook-form#13566) Revert "docs: fix grammar in demo descriptions (react-hook-form#13565)" (react-hook-form#13568) Revert "test: remove duplicate UseFieldArray slug (react-hook-form#13564)" (react-hook-form#13567) test: remove duplicate UseFieldArray slug (react-hook-form#13564) docs: fix grammar in demo descriptions (react-hook-form#13565) 🐞 fix(useController): reflect cleared parent object in controlled fields (react-hook-form#13550) (react-hook-form#13553) 📖 docs: replace dead /api links with /docs in locale READMEs (react-hook-form#13561) 🐛 fix(unset): guard against prototype keyword path traversal (react-hook-form#13559) (react-hook-form#13560) 📖 docs: replace retired /jp, /pt, /zh subdomain links in locale READMEs (react-hook-form#13556)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
unset()insrc/utils/unset.tstraverses path segments throughbaseGet()without checking for prototype-pollution keywords (__proto__,constructor,prototype). This allows callers to inadvertently (or maliciously) delete properties fromObject.prototype.set.tsalready contains an equivalent guard:but
unset.tswas never updated to match.Bug
The same issue occurs with array-form paths (
["__proto__", "polluted"]) and theconstructor/prototypekeywords.Fix
After computing the
pathsarray inunset(), bail out immediately (no-op) if any segment is inPROTOTYPE_KEYWORDS, mirroring the guard inset.ts.Verification
New test added to
src/__tests__/utils/unset.test.ts:unset({}, "__proto__.foo")deleted fromObject.prototype.Full utils suite still green: 134/134 tests pass.
Closes #13559