Skip to content

Security: Invalid config silently falls back to empty defaults, dropping all security controls #28140

@bobsahur-robot

Description

@bobsahur-robot

Summary

When openclaw.json contains an unrecognized key (e.g., skills.nano-banana-pro), config validation fails with INVALID_CONFIG. The error handler in src/config/io.ts:802 catches this and returns an empty object {}, silently discarding the entire configuration.

This means every setting falls back to its default value — including security-critical controls.

Impact

A single typo or unrecognized key anywhere in the config causes all of the following to silently revert to defaults:

  • tools.sessions.visibility → defaults to "tree" (may be more or less restrictive than intended)
  • channels.telegram.groups → group routing config lost
  • groupPolicy → reverts to default
  • Tool restrictions, model routing, session settings — all gone
  • Any security controls configured by the user are silently dropped

The gateway continues running with no visible error to the user (only a log line). The CLI shows a warning but the gateway daemon swallows it.

Root Cause

// src/config/io.ts:801-803
if (error?.code === "INVALID_CONFIG") {
  return {};  // ← entire config discarded
}

Validation is all-or-nothing: one invalid key → entire config rejected → empty fallback.

Reproduction

  1. Add any unrecognized key to openclaw.json (e.g., "skills": { "my-skill": { "env": { "KEY": "value" } } })
  2. Restart gateway
  3. Observe: tools.sessions.visibility (or any other setting) reverts to default
  4. Gateway logs show Invalid config but continues running with empty config

Discovered Via

Setting tools.sessions.visibility: "all" had no effect because an unrelated skills.nano-banana-pro key (documented in a skill's own SKILL.md as valid!) caused the entire config to be discarded. Took significant debugging to trace.

Proposed Fix Options

  1. Fail hard — refuse to start with invalid config. Safest. Forces user to fix before running. May be too disruptive for some users.
  2. Partial validation (strip and continue) — remove only unrecognized keys, keep everything else valid. This is what "best-effort" should mean. Zod's .passthrough() or .strip() could help here.
  3. Hybrid — strip unknown keys with a loud warning, but fail hard if a known key has an invalid value (type mismatch, constraint violation). This distinguishes "extra stuff I don't understand" from "broken stuff I do understand."

Option 3 seems like the right balance: forward-compatible (new skill keys don't break old versions) while still catching real config errors.

Additional Context

  • The skill SKILL.md for nano-banana-pro explicitly documents skills."nano-banana-pro".env.GEMINI_API_KEY as a valid config path, but the OpenClaw config schema doesn't support arbitrary skill keys. This mismatch makes it easy for users (or agents) to create invalid configs by following skill documentation.
  • Consider: should skills.* be a passthrough/record type to support per-skill config without schema changes?

Metadata

Metadata

Assignees

Labels

securitySecurity documentationstaleMarked as stale due to inactivity

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions