From 018494fa3ebb9145112e68b56fe1cb2e9f9a9ed6 Mon Sep 17 00:00:00 2001 From: Agustin Rivera <31522568+eleqtrizit@users.noreply.github.com> Date: Mon, 20 Apr 2026 11:43:30 -0700 Subject: [PATCH] fix(dotenv): reserve workspace OPENCLAW env namespace (#69376) --- CHANGELOG.md | 1 + src/infra/dotenv.test.ts | 4 ++++ src/infra/dotenv.ts | 3 +++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3d45bd71c6..e5a613fd3fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai - BlueBubbles: raise the outbound `/api/v1/message/text` send timeout default from 10s to 30s, and add a configurable `channels.bluebubbles.sendTimeoutMs` (also per-account) so macOS 26 setups where Private API iMessage sends stall for 60+ seconds no longer silently lose messages at the 10s abort. Probes, chat lookups, and health checks keep the shorter 10s default. Fixes #67486. (#69193) Thanks @omarshahine. - Context engine/plugins: stop rejecting third-party context engines whose `info.id` differs from the registered plugin slot id. The strict-match contract added in 2026.4.14 broke `lossless-claw` and other plugins whose internal engine id does not equal the slot id they are registered under, producing repeated `info.id must match registered id` lane failures on every turn. Fixes #66601. (#66678) Thanks @GodsBoy. - Agents/compaction: rename embedded Pi compaction lifecycle events to `compaction_start` / `compaction_end` so OpenClaw stays aligned with `pi-coding-agent` 0.66.1 event naming. (#67713) Thanks @mpz4life. +- Security/dotenv: block all `OPENCLAW_*` keys from untrusted workspace `.env` files so workspace-local env loading fails closed for new runtime-control variables instead of silently inheriting them. (#473) ## 2026.4.20 diff --git a/src/infra/dotenv.test.ts b/src/infra/dotenv.test.ts index 4652cded1c1..9e5617009bb 100644 --- a/src/infra/dotenv.test.ts +++ b/src/infra/dotenv.test.ts @@ -607,6 +607,10 @@ describe("workspace .env blocklist completeness", () => { await withIsolatedEnvAndCwd(async () => { await withDotEnvFixture(async ({ cwdDir }) => { const runtimeControlKeys = [ + "OPENCLAW_GIT_DIR", + "OPENCLAW_WORKSPACE_DIR", + "OPENCLAW_MDNS_HOSTNAME", + "OPENCLAW_SESSION_CACHE_TTL_MS", "OPENCLAW_UPDATE_PACKAGE_SPEC", "OPENCLAW_GATEWAY_PORT", "OPENCLAW_GATEWAY_URL", diff --git a/src/infra/dotenv.ts b/src/infra/dotenv.ts index 76af2982138..391c30778af 100644 --- a/src/infra/dotenv.ts +++ b/src/infra/dotenv.ts @@ -75,6 +75,9 @@ const BLOCKED_WORKSPACE_DOTENV_PREFIXES = [ "ANTHROPIC_API_KEY_", "CLAWHUB_", "OPENAI_API_KEY_", + // Workspace .env is untrusted; reserve the full OpenClaw runtime namespace + // for shell/global config so new OPENCLAW_* controls are fail-closed by default. + "OPENCLAW_", "OPENCLAW_CLAWHUB_", "OPENCLAW_DISABLE_", "OPENCLAW_SKIP_",