Skip to content

fix(utils): Remove dottie in favor of undot. update undot with security enhancements.#18137

Merged
WikiRik merged 2 commits into
sequelize:mainfrom
SippieCup:remove-dottie
Mar 3, 2026
Merged

fix(utils): Remove dottie in favor of undot. update undot with security enhancements.#18137
WikiRik merged 2 commits into
sequelize:mainfrom
SippieCup:remove-dottie

Conversation

@SippieCup
Copy link
Copy Markdown
Contributor

@SippieCup SippieCup commented Mar 3, 2026

This pull request adds important security enhancement to the core package undot by replacing the dottie dependency with undot for handling nested object paths, and by implementing the same protections found in the new dottie build against prototype pollution attacks. The changes affect both the implementation and testing of nested path access and mutation logic, ensuring that dangerous object keys cannot be used to manipulate object prototypes.

Dottie fixes: https://github.com/mickhansen/dottie.js/pull/43/changes

Pull Request Checklist

  • Have you added new tests to prevent regressions?
  • [x ] Did you update the typescript typings accordingly (if applicable)?
  • Does the description below contain a link to an existing issue (Closes #[issue]) or a description of the issue you are solving?
  • Does the name of your PR follow our conventions?

Description of Changes

###Security improvements

  • Replaced usage of the dottie package in model.js with custom functions getByPathArray, setByPathArray, and tokenizePath from utils/undot.js, eliminating an external dependency and allowing for tighter control over path parsing and setting. [1] [2] [3]
  • Added checks in tokenizePath, getByPathArray, and setByPathArray to detect and block dangerous key segments (__proto__, constructor, prototype) at any position, preventing prototype pollution vulnerabilities. [1] [2] [3] [4] [5]

###Testing and verification

  • Added unit tests in undot.test.ts to verify that prototype pollution attempts are blocked and that normal nested paths still work as expected. These tests cover various edge cases and ensure that the new logic is robust. [1] [2]

These changes add the security changes of dottie to undot by preventing known attack vectors while maintaining full functionality for safe keys. Then removes the dottie dependency in favor of undot.

List of Breaking Changes

Summary by CodeRabbit

  • Bug Fixes

    • Improved security by adding protections that prevent prototype pollution when accessing or updating nested data.
  • Refactor

    • Replaced an external nested-path dependency with internal utilities to streamline and harden nested-data handling.
  • Tests

    • Added extensive unit tests covering security guards, edge cases, and nested-key handling to prevent regressions.

Copilot AI review requested due to automatic review settings March 3, 2026 03:21
@SippieCup SippieCup requested a review from a team as a code owner March 3, 2026 03:21
@SippieCup SippieCup requested review from ephys and sdepold March 3, 2026 03:21
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 3, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaced use of the external dottie dependency in packages/core with in-repo path utilities. Added tokenizePath, getByPathArray, and setByPathArray with prototype-pollution guards blocking __proto__, constructor, and prototype.

Changes

Cohort / File(s) Summary
Dependency Removal
packages/core/package.json
Removed external dependency dottie.
Model updates
packages/core/src/model.js
Removed dottie import; now uses tokenizePath, getByPathArray, and setByPathArray from ./utils/undot.js to read/write nested values and maintain change tracking.
Utility implementation & guards
packages/core/src/utils/undot.ts
New/updated utilities: tokenizePath, precompileKeys, getByPathArray (exported), and setByPathArray; added prototype-pollution guards that reject __proto__, constructor, and prototype segments.
Tests
packages/core/test/unit/utils/undot.test.ts
Added extensive tests for tokenization, getByPathArray/setByPathArray, precompileKeys, transformRowWithPrecompiled, and prototype-pollution prevention across many edge cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • sdepold

Poem

🐇 I hopped through keys both safe and sly,
Kicked out proto tricks that lurk nearby.
Tokenized hops on a carrot trail,
Guards in place so nasties fail.
🥕 Hop, set, and fetch — no pollution left to try.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: removing the dottie dependency and replacing it with an internal undot implementation, while adding security enhancements to prevent prototype pollution attacks.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

@SippieCup SippieCup changed the title Remove dottie refactor(utils): Remove dottie in favor of undot. update undot with security enhancements. Mar 3, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the dottie dependency from @sequelize/core by switching nested-path read/write behavior to the internal undot utilities, and adds prototype-pollution protections to undot to block dangerous key segments.

Changes:

  • Add prototype-pollution guards to tokenizePath, precompileKeys, setByPathArray, and introduce getByPathArray in undot.
  • Update Model#set JSON nested-field handling to use undot instead of dottie.
  • Remove dottie from packages/core dependencies and add unit tests for the new protections.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

File Description
packages/core/src/utils/undot.ts Adds dangerous-segment detection, new getByPathArray, and guards in path tokenization + setter.
packages/core/src/model.js Replaces Dottie.get/set with getByPathArray / setByPathArray + tokenizePath for JSON dotted keys.
packages/core/test/unit/utils/undot.test.ts Adds unit tests targeting prototype-pollution prevention across undot helpers.
packages/core/package.json Removes the dottie dependency from core.

Comment thread packages/core/src/model.js Outdated
Comment thread packages/core/test/unit/utils/undot.test.ts Outdated
@SippieCup SippieCup changed the title refactor(utils): Remove dottie in favor of undot. update undot with security enhancements. fix(utils): Remove dottie in favor of undot. update undot with security enhancements. Mar 3, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/core/src/model.js (1)

3677-3681: Repeated tokenization of the same key.

tokenizePath(key) is called twice for the same key value. While not a significant performance issue in practice (this code path handles JSON attribute updates which are relatively infrequent), you could cache the result if this becomes a hot path.

Optional: Cache tokenized path
           if (key.includes('.') && jsonAttributeNames.has(key.split('.')[0])) {
-            const previousNestedValue = getByPathArray(this.dataValues, tokenizePath(key));
+            const path = tokenizePath(key);
+            const previousNestedValue = getByPathArray(this.dataValues, path);
             if (!isEqual(previousNestedValue, value)) {
-              setByPathArray(this.dataValues, tokenizePath(key), value);
+              setByPathArray(this.dataValues, path, value);
               this.changed(key.split('.')[0], true);
             }
           }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/model.js` around lines 3677 - 3681, tokenizePath(key) is
being called twice for the same key in the JSON update logic (used with
getByPathArray and setByPathArray); cache its result in a local variable (e.g.,
const path = tokenizePath(key)) and reuse that variable when calling
getByPathArray(this.dataValues, path) and setByPathArray(this.dataValues, path),
leaving the this.changed(key.split('.')[0], true) call unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/test/unit/utils/undot.test.ts`:
- Around line 621-629: The test name and behavior are mismatched: update the
spec for transformRowWithPrecompiled / precompileKeys to either reflect that
this is a normal dotted-key transformation (e.g., "should transform normal
dotted keys without pollution") or add a new test that actually exercises
blocking of "__proto__" (call precompileKeys with a key containing "__proto__"
like "user.__proto__.pollute" or a top-level "__proto__" dotted key, run
transformRowWithPrecompiled on a row that would attempt prototype pollution, and
assert the prototype was not polluted). Ensure the new or renamed test
references the same helpers (precompileKeys and transformRowWithPrecompiled) and
keeps the existing pollution assertion style.

---

Nitpick comments:
In `@packages/core/src/model.js`:
- Around line 3677-3681: tokenizePath(key) is being called twice for the same
key in the JSON update logic (used with getByPathArray and setByPathArray);
cache its result in a local variable (e.g., const path = tokenizePath(key)) and
reuse that variable when calling getByPathArray(this.dataValues, path) and
setByPathArray(this.dataValues, path), leaving the
this.changed(key.split('.')[0], true) call unchanged.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adf26ab and 122ba5c.

📒 Files selected for processing (4)
  • packages/core/package.json
  • packages/core/src/model.js
  • packages/core/src/utils/undot.ts
  • packages/core/test/unit/utils/undot.test.ts
💤 Files with no reviewable changes (1)
  • packages/core/package.json

Comment thread packages/core/test/unit/utils/undot.test.ts
- Replace external dottie dependency with internal undot utility for
  dot-path object access in model.js
- Add getByPathArray to undot.ts for nested value retrieval
- Guard against prototype pollution (__proto__, constructor, prototype)
  at all path positions in tokenizePath, precompileKeys, setByPathArray,
  and getByPathArray (CVE-2026-27837)
- Add comprehensive prototype pollution prevention tests
- Remove dottie from package.json dependencies
@WikiRik WikiRik enabled auto-merge (squash) March 3, 2026 06:44
@WikiRik WikiRik merged commit 9535903 into sequelize:main Mar 3, 2026
53 checks passed
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.

3 participants