Skip to content

Potential fix for code scanning alert no. 27: Prototype-polluting assignment#28

Merged
sebamar88 merged 1 commit intomainfrom
alert-autofix-27-b
Mar 31, 2026
Merged

Potential fix for code scanning alert no. 27: Prototype-polluting assignment#28
sebamar88 merged 1 commit intomainfrom
alert-autofix-27-b

Conversation

@sebamar88
Copy link
Copy Markdown
Owner

Potential fix for https://github.com/sebamar88/bytekit/security/code-scanning/27

General fix: Ensure that no untrusted path segment is ever used as a property name that could affect Object.prototype. That means validating every component of the dot‑separated path (including the last one) against a deny‑list of prototype‑polluting keys and rejecting/ignoring invalid paths before performing any assignment.

Best concrete fix here:

  1. Keep the existing BLOCKED_KEYS deny‑list.
  2. Replace the use of keys.at(-1)! with an explicit lastKey variable.
  3. Guard both intermediate and final keys:
    • Reject any path that:
      • Is empty/blank.
      • Contains any blocked key in any segment, including the last one.
  4. Use lastKey only after it has been verified as safe.

This preserves existing semantics (it still silently skips unsafe paths and uses Object.create(null) for new nested objects), but makes the sink at line 223 obviously unreachable for any prototype‑polluting key, and clearer for static analysis.

Concretely in src/utils/helpers/DiffUtils.ts:

  • In setNestedValue:
    • After computing keys, derive lastKey = keys[keys.length - 1].
    • Add an early return if !lastKey.
    • Keep or slightly tighten the blocked‑key check, now comparing all keys (including lastKey) against BLOCKED_KEYS.
    • Use lastKey instead of keys.at(-1)! for the final assignment.

No new imports or helper methods are required.

Suggested fixes powered by Copilot Autofix. Review carefully before merging.

…ignment

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@sebamar88 sebamar88 marked this pull request as ready for review March 31, 2026 19:43
@github-actions
Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA b9dc608.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@sebamar88 sebamar88 merged commit 7eaca13 into main Mar 31, 2026
9 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Total dist size: 1.3M

View detailed breakdown
4.0K	dist/api-client.d.ts
4.0K	dist/api-client.d.ts.map
4.0K	dist/api-client.js
4.0K	dist/api-client.js.map
112K	dist/cli
4.0K	dist/debug.d.ts
4.0K	dist/debug.d.ts.map
4.0K	dist/debug.js
4.0K	dist/debug.js.map
4.0K	dist/env-manager.d.ts
4.0K	dist/env-manager.d.ts.map
4.0K	dist/env-manager.js
4.0K	dist/env-manager.js.map
4.0K	dist/file-upload.d.ts
4.0K	dist/file-upload.d.ts.map
4.0K	dist/file-upload.js
4.0K	dist/file-upload.js.map
4.0K	dist/index.d.ts
4.0K	dist/index.d.ts.map
4.0K	dist/index.js
4.0K	dist/index.js.map
4.0K	dist/logger.d.ts
4.0K	dist/logger.d.ts.map
4.0K	dist/logger.js
4.0K	dist/logger.js.map
4.0K	dist/profiler.d.ts
4.0K	dist/profiler.d.ts.map
4.0K	dist/profiler.js
4.0K	dist/profiler.js.map
4.0K	dist/response-validator.d.ts
4.0K	dist/response-validator.d.ts.map
4.0K	dist/response-validator.js
4.0K	dist/response-validator.js.map
4.0K	dist/retry-policy.d.ts
4.0K	dist/retry-policy.d.ts.map
4.0K	dist/retry-policy.js
4.0K	dist/retry-policy.js.map
4.0K	dist/storage-utils.d.ts
4.0K	dist/storage-utils.d.ts.map
4.0K	dist/storage-utils.js
4.0K	dist/storage-utils.js.map
4.0K	dist/streaming.d.ts
4.0K	dist/streaming.d.ts.map
4.0K	dist/streaming.js
4.0K	dist/streaming.js.map
324K	dist/utils/core
336K	dist/utils/helpers
296K	dist/utils/async
976K	dist/utils
4.0K	dist/websocket.d.ts
4.0K	dist/websocket.d.ts.map
4.0K	dist/websocket.js
4.0K	dist/websocket.js.map

@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown
Contributor

📊 Code Coverage Report

Coverage: 99.44% ✅

Great coverage!

View full coverage report

}

current[keys.at(-1)!] = value;
current[lastKey] = value;

Check warning

Code scanning / CodeQL

Prototype-polluting function Medium

The property chain
here
is recursively assigned to
current
without guarding against prototype pollution.

Copilot Autofix

AI 5 days ago

General approach

To harden against prototype pollution, the deep assignment function must:

  1. Reject dangerous property names in any segment of the path (already done).
  2. Avoid traversing or depending on inherited properties when creating intermediate objects.
  3. Ensure intermediate containers are safe (no implicit link to Object.prototype).

Best concrete fix in this file

Within setNestedValue:

  • Replace if (!(key in current)) with a check that only considers own properties, e.g. Object.prototype.hasOwnProperty.call(current, key). This prevents the code from following or relying on inherited properties that might be polluted.
  • Keep the existing blocking of __proto__, constructor, and prototype and the use of Object.create(null) for new intermediate objects.
  • We do not need new imports; Object.prototype.hasOwnProperty is globally available.
  • The external behavior remains the same for normal objects: if an intermediate key is absent as an own property, we still create an object; if it exists as an own property, we reuse it. The only change is that inherited properties are now treated as absent, which is safer and consistent with typical expectations for nested data structures.

Specific change

In src/utils/helpers/DiffUtils.ts, in setNestedValue, adjust the loop over keys so that:

if (!(key in current)) {
    current[key] = Object.create(null);
}

becomes:

if (!Object.prototype.hasOwnProperty.call(current, key)) {
    current[key] = Object.create(null);
}

No other changes are needed.

Suggested changeset 1
src/utils/helpers/DiffUtils.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/utils/helpers/DiffUtils.ts b/src/utils/helpers/DiffUtils.ts
--- a/src/utils/helpers/DiffUtils.ts
+++ b/src/utils/helpers/DiffUtils.ts
@@ -218,7 +218,7 @@
 
         for (let i = 0; i < keys.length - 1; i++) {
             const key = keys[i];
-            if (!(key in current)) {
+            if (!Object.prototype.hasOwnProperty.call(current, key)) {
                 current[key] = Object.create(null);
             }
             current = current[key] as Record<string, unknown>;
EOF
@@ -218,7 +218,7 @@

for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!(key in current)) {
if (!Object.prototype.hasOwnProperty.call(current, key)) {
current[key] = Object.create(null);
}
current = current[key] as Record<string, unknown>;
Copilot is powered by AI and may make mistakes. Always verify output.
}

current[keys.at(-1)!] = value;
current[lastKey] = value;

Check warning

Code scanning / CodeQL

Prototype-polluting assignment Medium

This assignment may alter Object.prototype if a malicious '__proto__' string is injected from
library input
.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@github-actions
Copy link
Copy Markdown
Contributor

📊 Code Coverage Report

Coverage: %

❌ Low coverage - please add more tests

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/utils/helpers/DiffUtils.ts 75.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

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