{"id":"CVE-2026-32231","aliases":["EUVD-2026-11667","GHSA-46q5-g3j9-wx5c"],"status":"published","title":"ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data","description":"ZeptoClaw is a personal AI assistant. Prior to 0.7.6, the generic webhook channel trusts caller-supplied identity fields (sender, chat_id) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (auth_token: None), an attacker who can reach POST /webhook can spoof an allowlisted sender and choose arbitrary chat_id values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse. This vulnerability is fixed in 0.7.6.","severity":{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00209,"percentile":0.11175,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-306","CWE-345"],"published":"2026-03-12T16:36:48Z","modified":"2026-10-28T02:30:51Z","fixes":[{"ecosystem":"crates.io","package":"zeptoclaw","fixed_in":["0.7.6"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"zeptoclaw","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.7.5"},{"fixed":"0.7.6"}]}]},{"source":"osv","ecosystem":"crates.io","package":"zeptoclaw","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.7.6"}]}]}],"products":[{"vendor":"qhkm","product":"zeptoclaw"},{"vendor":"zeptoclaw","product":"zeptoclaw"}],"references":[{"url":"https://github.com/qhkm/zeptoclaw/security/advisories/GHSA-46q5-g3j9-wx5c","tags":["x_refsource_CONFIRM","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/qhkm/zeptoclaw/pull/324","tags":["x_refsource_MISC","Issue Tracking","Patch","fix","web"]},{"url":"https://github.com/qhkm/zeptoclaw/commit/bf004a20d3687a0c1a9e052ec79536e30d6de134","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://github.com/qhkm/zeptoclaw/releases/tag/v0.7.6","tags":["x_refsource_MISC","Patch","Release Notes","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32231","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-46q5-g3j9-wx5c"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/32xxx/CVE-2026-32231.json","tags":["advisory"]},{"url":"https://github.com/qhkm/zeptoclaw","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-32231","title":"ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data","description":"ZeptoClaw is a personal AI assistant. Prior to 0.7.6, the generic webhook channel trusts caller-supplied identity fields (sender, chat_id) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (auth_token: None), an attacker who can reach POST /webhook can spoof an allowlisted sender and choose arbitrary chat_id values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse. This vulnerability is fixed in 0.7.6.","status":"published","published":"2026-03-12T18:22:48.872Z","modified":"2026-03-12T20:47:02.636Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-306","CWE-345"],"updated_at":"2026-11-02T14:19:57.100857Z"}],"euvd":[{"id":"EUVD-2026-11667","description":"ZeptoClaw is a personal AI assistant. Prior to 0.7.6, the generic webhook channel trusts caller-supplied identity fields (sender, chat_id) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (auth_token: None), an attacker who can reach POST /webhook can spoof an allowlisted sender and choose arbitrary chat_id values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse. This vulnerability is fixed in 0.7.6.","status":"published","published":"2026-03-12T18:22:48Z","modified":"2026-03-12T20:47:02Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high"}],"updated_at":"2026-11-02T19:25:35.389351Z"}],"ghsa":[{"id":"GHSA-46q5-g3j9-wx5c","title":"ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data","description":"### Summary\nThe generic webhook channel trusts caller-supplied identity fields (`sender`, `chat_id`) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (`auth_token: None`), an attacker who can reach `POST /webhook` can spoof an allowlisted sender and choose arbitrary `chat_id` values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse.\n\n### Details\nRelevant code paths:\n\n- `src/channels/webhook.rs:121` sets runtime default `auth_token: None`.\n- `src/config/types.rs:910` also defaults webhook config `auth_token` to `None`.\n- `src/channels/webhook.rs:224` (`validate_auth`) explicitly allows requests when no token is configured.\n- `src/channels/webhook.rs:128` defines `WebhookPayload` with identity fields fully controlled by caller input:\n  - `sender: String`\n  - `chat_id: String`\n- `src/channels/webhook.rs:421` performs allowlist authorization using `payload.sender`.\n- `src/channels/webhook.rs:433` and `src/channels/webhook.rs:434` create `InboundMessage` using untrusted `payload.sender` and `payload.chat_id`.\n\nWhy this is vulnerable:\n\n- The system treats user-provided JSON identity as authoritative identity.\n- Allowlist enforcement does not verify sender authenticity beyond that payload value.\n- `chat_id` is also attacker-controlled, so routing/session association can be steered to arbitrary chats/conversations.\n- If the webhook is exposed without strong upstream authn/authz controls, spoofing is straightforward.\n\n### PoC\n1. Configure the webhook channel in a vulnerable posture (common default behavior):\n   - `enabled = true`\n   - `bind_address = \"0.0.0.0\"` (or any reachable interface)\n   - `port = 9876`\n   - `path = \"/webhook\"`\n   - `auth_token = null` (or omitted)\n   - `allow_from = [\"trusted-user-1\"]`\n   - `deny_by_default = true`\n2. Start ZeptoClaw.\n3. Send a forged request with attacker-chosen `sender` and `chat_id`, without any `Authorization` header:\n\n```bash\ncurl -i -X POST \"http://127.0.0.1:9876/webhook\" \\\n  -H \"Content-Type: application/json\" \\\n  --data '{\n    \"message\":\"FORGED: run privileged workflow\",\n    \"sender\":\"trusted-user-1\",\n    \"chat_id\":\"victim-chat-42\"\n  }'\n```\n\n4. Observe:\n   - Response is `HTTP/1.1 200 OK`.\n   - Message is accepted as if it originated from `trusted-user-1`.\n   - Message is routed under attacker-chosen `chat_id` (`victim-chat-42`).\n\n### Impact\n- Vulnerability type:\n  - Authentication/authorization bypass (identity spoofing)\n  - IDOR-style routing/control issue via attacker-chosen `chat_id`\n- Affected deployments:\n  - Any deployment exposing the generic webhook endpoint without strict upstream authentication and identity binding.\n- Security consequences:\n  - Forged inbound messages from spoofed trusted users.\n  - Bypass of allowlist intent by injecting allowlisted sender IDs in payload.\n  - Cross-chat/session contamination or hijacking by choosing arbitrary `chat_id`.\n  - Potential unauthorized downstream agent/tool actions triggered by malicious input.","status":"published","published":"2026-03-12T16:36:48Z","modified":"2026-03-13T13:35:56Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high"}],"cwes":["CWE-306","CWE-345"],"updated_at":"2026-11-02T14:39:35.644357Z"}],"nvd":[{"id":"CVE-2026-32231","description":"ZeptoClaw is a personal AI assistant. Prior to 0.7.6, the generic webhook channel trusts caller-supplied identity fields (sender, chat_id) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (auth_token: None), an attacker who can reach POST /webhook can spoof an allowlisted sender and choose arbitrary chat_id values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse. This vulnerability is fixed in 0.7.6.","status":"published","published":"2026-03-12T19:16:17.027Z","modified":"2026-06-17T10:35:23.55Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-306","CWE-345"],"updated_at":"2026-11-02T14:12:09.358914Z"}],"osv":[{"id":"CVE-2026-32231","title":"ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data","description":"ZeptoClaw is a personal AI assistant. Prior to 0.7.6, the generic webhook channel trusts caller-supplied identity fields (sender, chat_id) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (auth_token: None), an attacker who can reach POST /webhook can spoof an allowlisted sender and choose arbitrary chat_id values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse. This vulnerability is fixed in 0.7.6.","status":"published","published":"2026-03-12T18:22:48.872Z","modified":"2026-10-28T02:30:51.898181222Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high"}],"cwes":["CWE-306","CWE-345"],"updated_at":"2026-11-02T15:45:01.218144Z"},{"id":"GHSA-46q5-g3j9-wx5c","title":"ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data","description":"### Summary\nThe generic webhook channel trusts caller-supplied identity fields (`sender`, `chat_id`) from the request body and applies authorization checks to those untrusted values. Because authentication is optional and defaults to disabled (`auth_token: None`), an attacker who can reach `POST /webhook` can spoof an allowlisted sender and choose arbitrary `chat_id` values, enabling high-risk message spoofing and potential IDOR-style session/chat routing abuse.\n\n### Details\nRelevant code paths:\n\n- `src/channels/webhook.rs:121` sets runtime default `auth_token: None`.\n- `src/config/types.rs:910` also defaults webhook config `auth_token` to `None`.\n- `src/channels/webhook.rs:224` (`validate_auth`) explicitly allows requests when no token is configured.\n- `src/channels/webhook.rs:128` defines `WebhookPayload` with identity fields fully controlled by caller input:\n  - `sender: String`\n  - `chat_id: String`\n- `src/channels/webhook.rs:421` performs allowlist authorization using `payload.sender`.\n- `src/channels/webhook.rs:433` and `src/channels/webhook.rs:434` create `InboundMessage` using untrusted `payload.sender` and `payload.chat_id`.\n\nWhy this is vulnerable:\n\n- The system treats user-provided JSON identity as authoritative identity.\n- Allowlist enforcement does not verify sender authenticity beyond that payload value.\n- `chat_id` is also attacker-controlled, so routing/session association can be steered to arbitrary chats/conversations.\n- If the webhook is exposed without strong upstream authn/authz controls, spoofing is straightforward.\n\n### PoC\n1. Configure the webhook channel in a vulnerable posture (common default behavior):\n   - `enabled = true`\n   - `bind_address = \"0.0.0.0\"` (or any reachable interface)\n   - `port = 9876`\n   - `path = \"/webhook\"`\n   - `auth_token = null` (or omitted)\n   - `allow_from = [\"trusted-user-1\"]`\n   - `deny_by_default = true`\n2. Start ZeptoClaw.\n3. Send a forged request with attacker-chosen `sender` and `chat_id`, without any `Authorization` header:\n\n```bash\ncurl -i -X POST \"http://127.0.0.1:9876/webhook\" \\\n  -H \"Content-Type: application/json\" \\\n  --data '{\n    \"message\":\"FORGED: run privileged workflow\",\n    \"sender\":\"trusted-user-1\",\n    \"chat_id\":\"victim-chat-42\"\n  }'\n```\n\n4. Observe:\n   - Response is `HTTP/1.1 200 OK`.\n   - Message is accepted as if it originated from `trusted-user-1`.\n   - Message is routed under attacker-chosen `chat_id` (`victim-chat-42`).\n\n### Impact\n- Vulnerability type:\n  - Authentication/authorization bypass (identity spoofing)\n  - IDOR-style routing/control issue via attacker-chosen `chat_id`\n- Affected deployments:\n  - Any deployment exposing the generic webhook endpoint without strict upstream authentication and identity binding.\n- Security consequences:\n  - Forged inbound messages from spoofed trusted users.\n  - Bypass of allowlist intent by injecting allowlisted sender IDs in payload.\n  - Cross-chat/session contamination or hijacking by choosing arbitrary `chat_id`.\n  - Potential unauthorized downstream agent/tool actions triggered by malicious input.","status":"published","published":"2026-03-12T16:36:48Z","modified":"2026-03-13T13:57:12.965925Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"high"}],"cwes":["CWE-306","CWE-345"],"updated_at":"2026-11-02T15:46:36.434231Z"}]}}
