Skip to content

fix(security): replace in with Object.hasOwn in hasExplicitProviderAccountConfig#34995

Closed
manusjs wants to merge 1 commit intoopenclaw:mainfrom
manusjs:fix/prototype-pollution-has-explicit-provider-config
Closed

fix(security): replace in with Object.hasOwn in hasExplicitProviderAccountConfig#34995
manusjs wants to merge 1 commit intoopenclaw:mainfrom
manusjs:fix/prototype-pollution-has-explicit-provider-config

Conversation

@manusjs
Copy link
Copy Markdown

@manusjs manusjs commented Mar 4, 2026

What

Replace the in operator with Object.hasOwn() in hasExplicitProviderAccountConfig to prevent a prototype-pollution bypass.

Why

The in operator checks the full prototype chain, not just own properties. An attacker who can influence the accountId value (e.g. via a specially crafted channel sender ID) could supply __proto__, constructor, toString, or any other inherited property name. The check would return true, causing the function to treat the account as explicitly configured — potentially suppressing security warnings or granting unintended access classifications.

Fixes #34926

How

-  return accountId in accounts;
+  return Object.hasOwn(accounts, accountId);

Object.hasOwn() only checks own enumerable properties (Node.js 16.9+, all modern environments). It is functionally equivalent to the old check for all legitimate account IDs and explicitly rejects prototype-chain properties.

Testing

All 90 existing security audit tests pass:

vitest run src/security/audit.test.ts

Breaking Changes

None. All legitimate account IDs are own properties of the accounts config object. The only behavioral change is that crafted prototype-property names no longer produce false positives.

…AccountConfig

The `in` operator traverses the prototype chain, meaning a crafted
accountId such as '__proto__', 'constructor', or 'toString' would
erroneously return true — causing hasExplicitProviderAccountConfig to
treat non-existent accounts as explicitly configured.

Replace with Object.hasOwn() which only checks own enumerable
properties, eliminating the prototype-pollution bypass.

Fixes openclaw#34926
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 4, 2026

Greptile Summary

This PR replaces the in operator with Object.hasOwn() in hasExplicitProviderAccountConfig to close a prototype-pollution bypass where an attacker-controlled accountId (e.g. __proto__, constructor, toString) would be found on the prototype chain and cause the function to incorrectly return true, potentially misclassifying an account as explicitly configured.

  • The fix is minimal, correct, and well-scoped — the accounts object is already guarded by a typeof accounts !== "object" null-check immediately before the changed line, so Object.hasOwn receives a valid object.
  • Object.hasOwn() is the idiomatic modern alternative to both the in operator (which walks the prototype chain) and .hasOwnProperty() (which can be shadowed by own properties on the target object); it works correctly on Object.create(null) maps as well.
  • No breaking changes are introduced: legitimate account IDs are always own properties of the parsed config object, so all previously-passing lookups still return true.

Confidence Score: 5/5

  • This PR is safe to merge — it is a minimal, well-reasoned security hardening with no breaking changes.
  • The change is a single-line substitution with a clearly superior alternative. The surrounding null/type guard ensures Object.hasOwn always receives a valid object, the fix is backward-compatible for all real account IDs, and the motivation (prototype-chain lookup bypass) is legitimate and accurately described.
  • No files require special attention.

Last reviewed commit: 4d7ba95

@benediktjohannes
Copy link
Copy Markdown
Contributor

Hello @manusjs,

thank you very much for your contribution. I really appreciate your work. Since we already have another pull request that was opened earlier (#34929) addressing this issue, I recommend commenting on the other pull request if you would like to suggest any changes. Thank you very much nevertheless.

cc @shakkernerd, could you please close this so that we don’t run into confusion with multiple PRs? Thanks!

@dvrshil
Copy link
Copy Markdown
Contributor

dvrshil commented Mar 5, 2026

Thanks for the work, @manusjs. This issue has been addressed by maintainer-selected PR #34982 (tracking issue #34926).\n\nTo keep the queue clean, I’m closing this as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security]: Use of in operator in hasExplicitProviderAccountConfig can lead to prototype pollution bypass

3 participants