Skip to content

HIGH: Deep sanitize setState for prototype pollution #55

@thedhanawada

Description

@thedhanawada

Vulnerability

File: core/state/StateManager.js lines 105-121

Prototype pollution protection is shallow-only. Only top-level proto/constructor/prototype are deleted, but nested objects merged via spread without sanitization.

Current Code

// Sanitize keys to prevent prototype pollution
if (updates && typeof updates === 'object') {
  delete updates.__proto__;      // ❌ Only top level
  delete updates.constructor;
  delete updates.prototype;
}

// Then spread merge nested objects WITHOUT sanitizing them
const newState = {
  ...oldState,
  ...updates,
  metadata: updates.metadata ? { ...oldState.metadata, ...updates.metadata } : oldState.metadata,
  // ❌ updates.metadata.__proto__ NOT deleted before spread
};

Vulnerability Detail

Attacker can pollute nested object prototypes:

// Direct attack (BLOCKED)
stateManager.setState({ __proto__: { evil: true } });  // ✅ Deleted

// Nested attack (NOT BLOCKED)
stateManager.setState({
  metadata: { __proto__: { malicious: true } }
});
// Now: stateManager.state.metadata.__proto__.malicious === true  ❌ POLLUTED

// Also via filters
stateManager.setState({
  filters: { __proto__: { override: true } }
});
// ❌ Polluted

// Also via businessHours
stateManager.setState({
  businessHours: { __proto__: { invalid: true } }
});
// ❌ Polluted

Fix Required

  1. Implement deep recursive sanitization (delete proto at all nesting levels)
  2. Add schema validation (allowlist known state keys)
  3. Sanitize BEFORE merge operations, not after

Effort

~2 hours

Metadata

Metadata

Assignees

No one assigned

    Labels

    phase:0-foundationImmediate fixes and test infrastructurepriority:highImportant for next milestonetype:securitySecurity vulnerability or hardening

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions