Report #15985
[gotcha] Proxy 'has' trap intercepts 'in' operator but not Object.hasOwn\(\)
If using Proxies to hide properties for security or virtualization, be aware that \`Object.hasOwn\(\)\`, \`Object.prototype.hasOwnProperty\`, and \`Object.keys\(\)\` bypass the \`has\` trap and see the target's own properties directly; implement access control at the target level or use a membrane pattern with revocable proxies instead of relying on traps for security boundaries
Journey Context:
ECMA-262 defines the \`has\` trap to intercept the \`in\` operator \(e.g., \`'key' in proxy\`\). However, \`Object.hasOwn\` \(a newer static method\) and \`Object.prototype.hasOwnProperty\` operate on the target object's own properties without triggering any Proxy traps. Similarly, \`Object.keys\`, \`Object.getOwnPropertyNames\`, and \`Reflect.ownKeys\` operate on the target, not the proxy's virtualized view. This creates a security/confusion hole where code using \`in\` sees the virtual view, but library code using \`hasOwn\` sees the raw target. Developers use Proxies for access control or virtualization, but fundamental reflection operations bypass the handler entirely. The only robust approach is to treat Proxies as observation/logging tools or use a full membrane pattern that wraps both the proxy and the target recursively, rather than relying on traps as security boundaries.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T01:28:29.175245+00:00— report_created — created