CVE-2026-56832: Praisonai PraisonAI DiscordApproval Accepts Unrelated Channel Vulnerability

HIGH
Advisory Identifier: GHSA-8579-rgg5-ph2m
CVSS 8.8
CWE-345 CWE-863
Published
Advisory Summary

CVE-2026-56832 is a HIGH (CVSS 8.8) praisonai discordapproval accepts unrelated channel vulnerability (CWE-345: Insufficient Verification of Data Authenticity) affecting Praisonai libraries in the PyPI ecosystem. The issue involves praisonai discordapproval accepts unrelated channel messages as dangerous-tool approvals. Remediation is available by upgrading affected packages to version 4.6.59.

CVE-2026-56832 at a Glance

CVE Identifier CVE-2026-56832
GHSA Identifier GHSA-8579-rgg5-ph2m
Severity HIGH
CVSS v3.1 Base Score 8.8
CWE Classification CWE-345: Insufficient Verification of Data Authenticity
Affected Product Praisonai
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 8.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-56832

To remediate this vulnerability, upgrade all affected Praisonai dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

praisonai fixed: 4.6.59
pip install praisonai>=4.6.59
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show praisonai

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-56832, inspect your installed packages using pip:

pip show praisonai

Analyze the terminal output to locate any version of Praisonai in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.6.59), your application is affected.

Note: The pip show praisonai command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-345: Insufficient Verification of Data Authenticity, where the product does not sufficiently verify the origin or authenticity of data, in a way that causes it to accept invalid data. In Praisonai, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

# DiscordApproval accepts unrelated channel messages as dangerous-tool approvals ## Summary `praisonai.bots.DiscordApproval` approves a pending dangerous tool call when it sees any later non-bot message in the configured Discord channel whose text is classified as approval, such as `yes`. The decision is not bound to: - a Discord reply to the approval message; - a Discord thread created for that request; - a Discord interaction/button callback for that request; - an explicit approver user allowlist; or - an approval nonce visible only to intended approvers. As a result, any user who can post in the configured approval channel can approve a pending high-risk tool call by sending `yes` after the approval message appears. The same local PoV also shows that the Slack and Telegram messaging approval backends have no explicit approver allowlist parameter, but the primary report-grade issue is the Discord backend's unthreaded channel cross-talk: the approving message does not need to be a reply or otherwise request-bound. ## Affected Product - Repository: `MervinPraison/PraisonAI` - Ecosystem: `pip` - Package: `praisonai` - Component: Python messaging approval backends - Primary affected file: `src/praisonai/praisonai/bots/_discord_approval.py` - Related sibling files: - `src/praisonai/praisonai/bots/_slack_approval.py` - `src/praisonai/praisonai/bots/_telegram_approval.py` - Latest PyPI version validated: `4.6.58` - Current `origin/main` validated: `1ad58ca02975ff1398efeda694ea2ab78f20cf3e` - Current `origin/main` tag validated: `v4.6.58` Suggested affected range: ```text pip:praisonai >= 4.5.2, <= 4.6.58 ``` Representative local sweep: ```text 4.5.0 Discord approval backend not present 4.5.2 vulnerable 4.5.128 vulnerable 4.6.9 vulnerable 4.6.10 vulnerable 4.6.56 vulnerable 4.6.57 vulnerable 4.6.58 vulnerable ``` ## Root Cause `DiscordApproval.request_approval()` posts an approval message to the configured channel and records the returned message id. `_poll_for_response()` then polls channel history with: ```python f"/channels/{channel_id}/messages?after={message_id}&limit=10" ``` For each later non-bot message, it reads `content`, classifies the text, and returns `ApprovalDecision(approved=True)` when the text is `approve`/`yes`. There is no check that the message is a Discord reply to the approval message, belongs to a request-specific thread, came from an intended approver, or contains a request-specific approval token. Important source evidence from `origin/main`: - `_discord_approval.py` lines 57-73: constructor accepts `token`, `channel_id`, `timeout`, and `poll_interval`; no approver allowlist. - `_discord_approval.py` line 239: polls all messages after the approval message in the configured channel. - `_discord_approval.py` lines 252-265: skips bot messages, classifies the remaining text, and approves when the keyword is `approve`. The Slack and Telegram backends are better request-scoped than Discord: - Slack uses `conversations.replies` for the approval message thread. - Telegram checks the callback/reply message id. However, both still lack an explicit approver identity parameter. They are included in the PoV and suggested fix because the authorization model should be consistent across all messaging approval backends. ## Local PoV Run against the latest local checkout: ```bash python3 poc/pov_prai_cand_029_messaging_approval_channel_member_bypass.py \ --repo ../../artifacts/repos/praisonai-v4.6.58 \ --json ``` The PoV is local-only. It mocks Slack, Telegram, and Discord API helpers in-process and does not contact those services. For Discord, the mock sequence is: 1. `DiscordApproval` posts a critical `execute_command` approval request to `D_APPROVAL_CHANNEL`. 2. The mocked channel-history endpoint returns a later ordinary non-bot channel message from `D_INTRUDER` with content `yes`. 3. `DiscordApproval` returns `approved=True` and `approver="D_INTRUDER"`. Observed output from `evidence/pov-v4.6.58.json`: ```json { "approval_from_unconfigured_channel_participant": { "discord": true, "slack": true, "telegram": true }, "backends": [ { "backend": "discord", "configured_channel_id": "D_APPROVAL_CHANNEL", "decision_approved": true, "decision_approver": "D_INTRUDER", "decision_reason": "Approved via Discord by intruder", "intruder_user": "D_INTRUDER" } ], "no_explicit_approver_allowlist_parameters": true, "vulnerable": true } ``` The command in the approval request is a harmless local sentinel: `touch /tmp/prai-cand-029`. The PoV stops at the approval decision; it does not execute the tool. ## Why This Is Not Intended Behavior This report does not claim that a deliberately private approval channel with only trusted approvers is unsafe by itself. The narrower issue is that the Discord backend treats an unrelated later channel message as the approval decision for a specific dangerous tool request. PraisonAI's approval documentation describes approval as a safety control that pauses before dangerous tools and asks a human or channel to allow or deny the specific request. A random later `yes` in the channel is not evidence that an intended approver reviewed that request. The existing Slack and Telegram implementations already show request-binding patterns that Discord lacks: - Slack scopes to replies for the approval message timestamp. - Telegram checks the callback/reply `message_id`. The Discord backend should provide at least the same request binding and should also support explicit approver identity checks for deployments where channel membership is broader than approval authority. ## Impact If an application uses `DiscordApproval` for dangerous tools such as shell commands, file writes, deletes, deployments, or other privileged operations, a low-privileged Discord user with write access to the configured approval channel can approve pending dangerous tool executions. This can lead to code execution, file modification, deployment changes, or data access with the privileges of the PraisonAI process, depending on which tools the agent exposes behind approval. The attacker does not need the LLM API key, shell access, repository access, or PraisonAI process access. They only need to be able to post an approval-looking message in the configured approval channel after the approval prompt appears. ## Severity Suggested severity: High. Rationale: - `AV`: the attacker interacts through a networked Discord channel. - `AC`: sending `yes` after an approval prompt is enough. - `PR`: the attacker needs permission to post in the configured approval channel, but no approver-specific permission. - `UI`: no separate victim interaction is needed after the prompt exists. - `S`: the vulnerable approval backend and approved tool run in the PraisonAI application's security scope. - `C/I/A`: approved dangerous tools can disclose, modify, or destroy data depending on the configured agent tools. ## Remediation Recommended fixes: 1. For Discord, require approvals to be tied to the request, not merely any later channel message. Use Discord interactions/buttons with opaque server-side request ids, or require a Discord reply whose `message_reference.message_id` matches the approval message. 2. Add explicit approver identity configuration to all messaging approval backends, for example `approver_user_ids` or `allowed_approvers`. 3. Reject approvals from users outside the configured approver set, even if the message appears in the configured channel. 4. Include a per-request nonce or opaque approval id in callbacks and verify it server side before returning `ApprovalDecision(approved=True)`. 5. Add regression tests for Discord where: - an unrelated later `yes` in the channel is ignored; - a reply from a non-approver is ignored; - a request-bound reply/callback from an allowed approver succeeds.

CVE-2026-56832 Affected Praisonai Versions

1 component(s)
Fixed Versions:
4.6.59
Product / Package Ecosystem Affected Versions Fixed Version
praisonai
PyPI
≥ 4.5.2
< 4.6.59
4.6.59

References

Frequently Asked Questions

What is CVE-2026-56832?
CVE-2026-56832 is a security vulnerability in Praisonai involving PraisonAI DiscordApproval accepts unrelated channel messages as dangerous-tool approvals under CWE-345: Insufficient Verification of Data Authenticity.
Which Praisonai versions are affected?
Affected versions include releases prior to 4.6.59 across affected packages: praisonai.
What version fixes CVE-2026-56832?
Upgrading to 4.6.59 (or the latest patched release for your respective branch) resolves the vulnerability.
Is praisonai affected?
Yes, praisonai is affected in releases prior to 4.6.59. Upgrade your dependency to 4.6.59 or later.
What is the CVSS score of CVE-2026-56832?
CVE-2026-56832 has a CVSS v3.1 base score of 8.8 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-56832?
CVE-2026-56832 is classified under CWE-345: Insufficient Verification of Data Authenticity (The product does not sufficiently verify the origin or authenticity of data, in a way that causes it to accept invalid data.).
How can I check PyPI dependencies for CVE-2026-56832?
Run the dependency tree command: 'pip show praisonai'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-8579-rgg5-ph2m",
  "modified" : "2026-07-20T21:23:11Z",
  "published" : "2026-06-18T13:52:27Z",
  "aliases" : [ "CVE-2026-56832" ],
  "summary" : "PraisonAI DiscordApproval accepts unrelated channel messages as dangerous-tool approvals",
  "details" : "# DiscordApproval accepts unrelated channel messages as dangerous-tool approvals\n\n## Summary\n\n`praisonai.bots.DiscordApproval` approves a pending dangerous tool call when it\nsees any later non-bot message in the configured Discord channel whose text is\nclassified as approval, such as `yes`.\n\nThe decision is not bound to:\n\n- a Discord reply to the approval message;\n- a Discord thread created for that request;\n- a Discord interaction/button callback for that request;\n- an explicit approver user allowlist; or\n- an approval nonce visible only to intended approvers.\n\nAs a result, any user who can post in the configured approval channel can\napprove a pending high-risk tool call by sending `yes` after the approval\nmessage appears. The same local PoV also shows that the Slack and Telegram\nmessaging approval backends have no explicit approver allowlist parameter, but\nthe primary report-grade issue is the Discord backend's unthreaded channel\ncross-talk: the approving message does not need to be a reply or otherwise\nrequest-bound.\n\n## Affected Product\n\n- Repository: `MervinPraison/PraisonAI`\n- Ecosystem: `pip`\n- Package: `praisonai`\n- Component: Python messaging approval backends\n- Primary affected file: `src/praisonai/praisonai/bots/_discord_approval.py`\n- Related sibling files:\n  - `src/praisonai/praisonai/bots/_slack_approval.py`\n  - `src/praisonai/praisonai/bots/_telegram_approval.py`\n- Latest PyPI version validated: `4.6.58`\n- Current `origin/main` validated:\n  `1ad58ca02975ff1398efeda694ea2ab78f20cf3e`\n- Current `origin/main` tag validated: `v4.6.58`\n\nSuggested affected range:\n\n```text\npip:praisonai >= 4.5.2, <= 4.6.58\n```\n\nRepresentative local sweep:\n\n```text\n4.5.0    Discord approval backend not present\n4.5.2    vulnerable\n4.5.128  vulnerable\n4.6.9    vulnerable\n4.6.10   vulnerable\n4.6.56   vulnerable\n4.6.57   vulnerable\n4.6.58   vulnerable\n```\n\n## Root Cause\n\n`DiscordApproval.request_approval()` posts an approval message to the configured\nchannel and records the returned message id.\n\n`_poll_for_response()` then polls channel history with:\n\n```python\nf\"/channels/{channel_id}/messages?after={message_id}&limit=10\"\n```\n\nFor each later non-bot message, it reads `content`, classifies the text, and\nreturns `ApprovalDecision(approved=True)` when the text is `approve`/`yes`.\nThere is no check that the message is a Discord reply to the approval message,\nbelongs to a request-specific thread, came from an intended approver, or\ncontains a request-specific approval token.\n\nImportant source evidence from `origin/main`:\n\n- `_discord_approval.py` lines 57-73: constructor accepts `token`,\n  `channel_id`, `timeout`, and `poll_interval`; no approver allowlist.\n- `_discord_approval.py` line 239: polls all messages after the approval\n  message in the configured channel.\n- `_discord_approval.py` lines 252-265: skips bot messages, classifies the\n  remaining text, and approves when the keyword is `approve`.\n\nThe Slack and Telegram backends are better request-scoped than Discord:\n\n- Slack uses `conversations.replies` for the approval message thread.\n- Telegram checks the callback/reply message id.\n\nHowever, both still lack an explicit approver identity parameter. They are\nincluded in the PoV and suggested fix because the authorization model should be\nconsistent across all messaging approval backends.\n\n## Local PoV\n\nRun against the latest local checkout:\n\n```bash\npython3 poc/pov_prai_cand_029_messaging_approval_channel_member_bypass.py \\\n  --repo ../../artifacts/repos/praisonai-v4.6.58 \\\n  --json\n```\n\nThe PoV is local-only. It mocks Slack, Telegram, and Discord API helpers\nin-process and does not contact those services.\n\nFor Discord, the mock sequence is:\n\n1. `DiscordApproval` posts a critical `execute_command` approval request to\n   `D_APPROVAL_CHANNEL`.\n2. The mocked channel-history endpoint returns a later ordinary non-bot\n   channel message from `D_INTRUDER` with content `yes`.\n3. `DiscordApproval` returns `approved=True` and `approver=\"D_INTRUDER\"`.\n\nObserved output from `evidence/pov-v4.6.58.json`:\n\n```json\n{\n  \"approval_from_unconfigured_channel_participant\": {\n    \"discord\": true,\n    \"slack\": true,\n    \"telegram\": true\n  },\n  \"backends\": [\n    {\n      \"backend\": \"discord\",\n      \"configured_channel_id\": \"D_APPROVAL_CHANNEL\",\n      \"decision_approved\": true,\n      \"decision_approver\": \"D_INTRUDER\",\n      \"decision_reason\": \"Approved via Discord by intruder\",\n      \"intruder_user\": \"D_INTRUDER\"\n    }\n  ],\n  \"no_explicit_approver_allowlist_parameters\": true,\n  \"vulnerable\": true\n}\n```\n\nThe command in the approval request is a harmless local sentinel:\n`touch /tmp/prai-cand-029`. The PoV stops at the approval decision; it does not\nexecute the tool.\n\n## Why This Is Not Intended Behavior\n\nThis report does not claim that a deliberately private approval channel with\nonly trusted approvers is unsafe by itself. The narrower issue is that the\nDiscord backend treats an unrelated later channel message as the approval\ndecision for a specific dangerous tool request.\n\nPraisonAI's approval documentation describes approval as a safety control that\npauses before dangerous tools and asks a human or channel to allow or deny the\nspecific request. A random later `yes` in the channel is not evidence that an\nintended approver reviewed that request.\n\nThe existing Slack and Telegram implementations already show request-binding\npatterns that Discord lacks:\n\n- Slack scopes to replies for the approval message timestamp.\n- Telegram checks the callback/reply `message_id`.\n\nThe Discord backend should provide at least the same request binding and should\nalso support explicit approver identity checks for deployments where channel\nmembership is broader than approval authority.\n\n## Impact\n\nIf an application uses `DiscordApproval` for dangerous tools such as shell\ncommands, file writes, deletes, deployments, or other privileged operations, a\nlow-privileged Discord user with write access to the configured approval channel\ncan approve pending dangerous tool executions.\n\nThis can lead to code execution, file modification, deployment changes, or data\naccess with the privileges of the PraisonAI process, depending on which tools\nthe agent exposes behind approval.\n\nThe attacker does not need the LLM API key, shell access, repository access, or\nPraisonAI process access. They only need to be able to post an approval-looking\nmessage in the configured approval channel after the approval prompt appears.\n\n## Severity\n\nSuggested severity: High.\n\nRationale:\n\n- `AV`: the attacker interacts through a networked Discord channel.\n- `AC`: sending `yes` after an approval prompt is enough.\n- `PR`: the attacker needs permission to post in the configured approval\n  channel, but no approver-specific permission.\n- `UI`: no separate victim interaction is needed after the prompt exists.\n- `S`: the vulnerable approval backend and approved tool run in the PraisonAI\n  application's security scope.\n- `C/I/A`: approved dangerous tools can disclose, modify, or destroy data\n  depending on the configured agent tools.\n\n## Remediation\n\nRecommended fixes:\n\n1. For Discord, require approvals to be tied to the request, not merely any\n   later channel message. Use Discord interactions/buttons with opaque\n   server-side request ids, or require a Discord reply whose\n   `message_reference.message_id` matches the approval message.\n2. Add explicit approver identity configuration to all messaging approval\n   backends, for example `approver_user_ids` or `allowed_approvers`.\n3. Reject approvals from users outside the configured approver set, even if the\n   message appears in the configured channel.\n4. Include a per-request nonce or opaque approval id in callbacks and verify it\n   server side before returning `ApprovalDecision(approved=True)`.\n5. Add regression tests for Discord where:\n   - an unrelated later `yes` in the channel is ignored;\n   - a reply from a non-approver is ignored;\n   - a request-bound reply/callback from an allowed approver succeeds.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "praisonai"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "4.5.2"
      }, {
        "fixed" : "4.6.59"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 4.6.58"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-8579-rgg5-ph2m"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/MervinPraison/PraisonAI"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-345", "CWE-863" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-18T13:52:27Z",
    "nvd_published_at" : null
  }
}