Every CVE Search/ Get API key

CVE-2026-56836

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

8.2 HighFix available

PraisonAI is a multi-agent teams system. From version 4.5.112 to before version 4.6.59, PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication. It prints a deprecation warning, and then launches the server. Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This issue has been patched in version 4.6.59.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
High
Availability
None

Exploit likelihood

0.33%Down 0.1 points since Oct 24, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.2

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

PraisonAI is a multi-agent teams system. From version 4.5.112 to before version 4.6.59, PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication. It prints a deprecation warning, and then launches the server. Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This issue has been patched in version 4.6.59.

Record
CVE-2026-56836
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-287, CWE-306, CWE-862
Updated
2026-11-02
EUVDEUVD-2026-108877 8.2

PraisonAI is a multi-agent teams system. From version 4.5.112 to before version 4.6.59, PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication. It prints a deprecation warning, and then launches the server. Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This issue has been patched in version 4.6.59.

Record
EUVD-2026-108877
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-5qw8-f2g9-ff29 8.2

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

Summary

PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py.

That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication:

praisonai recipe serve --host 0.0.0.0 --admin

It prints a deprecation warning, then launches the server with:

{
  "host": "0.0.0.0",
  "config": {
    "cors_origins": "*",
    "enable_admin": true
  }
}

Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload.

This is an incomplete hardening / sibling-callsite issue. The legacy feature handler in src/praisonai/praisonai/cli/features/recipe.py rejects the same non-localhost/no-auth combination, and current create_auth_middleware() now fails closed if API-key/JWT auth is selected without a secret. The installed Typer command bypasses both expectations by never requiring or setting auth.

Affected product

  • Repository: MervinPraison/PraisonAI
  • Package: praisonai
  • Component:
    • src/praisonai/praisonai/__main__.py
    • src/praisonai/praisonai/cli/app.py
    • src/praisonai/praisonai/cli/commands/recipe.py
    • src/praisonai/praisonai/cli/features/recipe.py
    • src/praisonai/praisonai/recipe/serve.py

Confirmed affected:

v4.6.58  1ad58ca02975ff1398efeda694ea2ab78f20cf3e
v4.6.57  e90d92231853161ad931f3498da57651a9f8b528
v4.6.56  d3c4a2afadfbf3a3e172e460e607ba4efad263a6
v4.6.34  e5928449f73f66cc8af1de61621aa974ab255133
v4.6.33  dfbb8d78ec7e8dc7118bc722ab1b2524bc98ddab
v4.6.10  4b1b17b963cbd0625e41394a30168c95b26429b2
v4.5.128 b4e3a8a84ade44ac3dd9102b792cdb4311a95937
v4.5.112 bfe3d94bad6db92fc2927c2e3c081ae8303e209e

Suggested affected range: praisonai >= 4.5.112, <= 4.6.58.

The lower bound is conservative and based on sampled tags. Maintainers should confirm the exact introduction point before publishing a final range.

Root cause

The installed entrypoint routes registered Typer commands before falling back to the legacy dispatcher:

if first_cmd in _get_typer_commands():
    _run_typer(argv)
else:
    _run_legacy(argv)

cli/app.py registers commands.recipe as the recipe Typer command:

from .commands.recipe import app as recipe_app
...
app.add_typer(recipe_app, name="recipe", help="Recipe management")

The deprecated Typer recipe serve implementation accepts a remote host, defaults CORS to *, and only enables authentication when --api-key is explicitly provided:

host: str = typer.Option("127.0.0.1", "--host", "-h", ...)
api_key: str = typer.Option(None, "--api-key", ...)
cors: str = typer.Option("*", "--cors", ...)
admin: bool = typer.Option(False, "--admin", ...)
...
serve_config = {}
...
if api_key:
    serve_config["api_key"] = api_key
    serve_config["auth"] = "api-key"
if cors:
    serve_config["cors_origins"] = cors
if admin:
    serve_config["enable_admin"] = True
...
serve(host=host, port=port, reload=reload, config=serve_config, workers=workers)

There is no equivalent to the hardened non-localhost guard in the legacy feature handler:

if host != "127.0.0.1" and host != "localhost" and auth == "none":
    self._print_error("Auth required for non-localhost binding. Use --auth api-key or --auth jwt")
    return self.EXIT_POLICY_DENIED

The Recipe server only installs auth middleware when config["auth"] is set:

auth_type = config.get("auth")
if auth_type and auth_type != "none":
    auth_middleware = create_auth_middleware(...)
    if auth_middleware:
        middleware.append(Middleware(auth_middleware))

On current v4.6.58, the…

Record
GHSA-5qw8-f2g9-ff29
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-287, CWE-306, CWE-862
Updated
2026-11-02
NVD 8.2

PraisonAI is a multi-agent teams system. From version 4.5.112 to before version 4.6.59, PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication. It prints a deprecation warning, and then launches the server. Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This issue has been patched in version 4.6.59.

Record
CVE-2026-56836
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-287, CWE-306, CWE-862
Updated
2026-11-02
OSV 8.2

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

PraisonAI is a multi-agent teams system. From version 4.5.112 to before version 4.6.59, PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py. That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication. It prints a deprecation warning, and then launches the server. Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload. This issue has been patched in version 4.6.59.

Record
CVE-2026-56836
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-287, CWE-306, CWE-862
Updated
2026-11-02
OSVGHSA-5qw8-f2g9-ff29 8.2

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

Summary

PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py.

That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication:

praisonai recipe serve --host 0.0.0.0 --admin

It prints a deprecation warning, then launches the server with:

{
  "host": "0.0.0.0",
  "config": {
    "cors_origins": "*",
    "enable_admin": true
  }
}

Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload.

This is an incomplete hardening / sibling-callsite issue. The legacy feature handler in src/praisonai/praisonai/cli/features/recipe.py rejects the same non-localhost/no-auth combination, and current create_auth_middleware() now fails closed if API-key/JWT auth is selected without a secret. The installed Typer command bypasses both expectations by never requiring or setting auth.

Affected product

  • Repository: MervinPraison/PraisonAI
  • Package: praisonai
  • Component:
    • src/praisonai/praisonai/__main__.py
    • src/praisonai/praisonai/cli/app.py
    • src/praisonai/praisonai/cli/commands/recipe.py
    • src/praisonai/praisonai/cli/features/recipe.py
    • src/praisonai/praisonai/recipe/serve.py

Confirmed affected:

v4.6.58  1ad58ca02975ff1398efeda694ea2ab78f20cf3e
v4.6.57  e90d92231853161ad931f3498da57651a9f8b528
v4.6.56  d3c4a2afadfbf3a3e172e460e607ba4efad263a6
v4.6.34  e5928449f73f66cc8af1de61621aa974ab255133
v4.6.33  dfbb8d78ec7e8dc7118bc722ab1b2524bc98ddab
v4.6.10  4b1b17b963cbd0625e41394a30168c95b26429b2
v4.5.128 b4e3a8a84ade44ac3dd9102b792cdb4311a95937
v4.5.112 bfe3d94bad6db92fc2927c2e3c081ae8303e209e

Suggested affected range: praisonai >= 4.5.112, <= 4.6.58.

The lower bound is conservative and based on sampled tags. Maintainers should confirm the exact introduction point before publishing a final range.

Root cause

The installed entrypoint routes registered Typer commands before falling back to the legacy dispatcher:

if first_cmd in _get_typer_commands():
    _run_typer(argv)
else:
    _run_legacy(argv)

cli/app.py registers commands.recipe as the recipe Typer command:

from .commands.recipe import app as recipe_app
...
app.add_typer(recipe_app, name="recipe", help="Recipe management")

The deprecated Typer recipe serve implementation accepts a remote host, defaults CORS to *, and only enables authentication when --api-key is explicitly provided:

host: str = typer.Option("127.0.0.1", "--host", "-h", ...)
api_key: str = typer.Option(None, "--api-key", ...)
cors: str = typer.Option("*", "--cors", ...)
admin: bool = typer.Option(False, "--admin", ...)
...
serve_config = {}
...
if api_key:
    serve_config["api_key"] = api_key
    serve_config["auth"] = "api-key"
if cors:
    serve_config["cors_origins"] = cors
if admin:
    serve_config["enable_admin"] = True
...
serve(host=host, port=port, reload=reload, config=serve_config, workers=workers)

There is no equivalent to the hardened non-localhost guard in the legacy feature handler:

if host != "127.0.0.1" and host != "localhost" and auth == "none":
    self._print_error("Auth required for non-localhost binding. Use --auth api-key or --auth jwt")
    return self.EXIT_POLICY_DENIED

The Recipe server only installs auth middleware when config["auth"] is set:

auth_type = config.get("auth")
if auth_type and auth_type != "none":
    auth_middleware = create_auth_middleware(...)
    if auth_middleware:
        middleware.append(Middleware(auth_middleware))

On current v4.6.58, the…

Record
GHSA-5qw8-f2g9-ff29
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-287, CWE-306, CWE-862
Updated
2026-11-02
OSVPYSEC-2026-3502 8.2

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

PraisonAI recipe serve Typer command bypasses the non-localhost authentication guard

Summary

PraisonAI's installed console entrypoint is Typer-first. In current releases, the recipe command is registered in the Typer app and praisonai recipe serve dispatches to the deprecated Typer command in src/praisonai/praisonai/cli/commands/recipe.py.

That Typer command can start the Recipe HTTP server on a non-localhost interface with no authentication:

praisonai recipe serve --host 0.0.0.0 --admin

It prints a deprecation warning, then launches the server with:

{
  "host": "0.0.0.0",
  "config": {
    "cors_origins": "*",
    "enable_admin": true
  }
}

Because config.auth is absent, create_app() does not attach the API-key or JWT middleware. Unauthenticated requests can then reach the recipe API and, when enabled, /admin/reload.

This is an incomplete hardening / sibling-callsite issue. The legacy feature handler in src/praisonai/praisonai/cli/features/recipe.py rejects the same non-localhost/no-auth combination, and current create_auth_middleware() now fails closed if API-key/JWT auth is selected without a secret. The installed Typer command bypasses both expectations by never requiring or setting auth.

Affected product

  • Repository: MervinPraison/PraisonAI
  • Package: praisonai
  • Component:
    • src/praisonai/praisonai/__main__.py
    • src/praisonai/praisonai/cli/app.py
    • src/praisonai/praisonai/cli/commands/recipe.py
    • src/praisonai/praisonai/cli/features/recipe.py
    • src/praisonai/praisonai/recipe/serve.py

Confirmed affected:

v4.6.58  1ad58ca02975ff1398efeda694ea2ab78f20cf3e
v4.6.57  e90d92231853161ad931f3498da57651a9f8b528
v4.6.56  d3c4a2afadfbf3a3e172e460e607ba4efad263a6
v4.6.34  e5928449f73f66cc8af1de61621aa974ab255133
v4.6.33  dfbb8d78ec7e8dc7118bc722ab1b2524bc98ddab
v4.6.10  4b1b17b963cbd0625e41394a30168c95b26429b2
v4.5.128 b4e3a8a84ade44ac3dd9102b792cdb4311a95937
v4.5.112 bfe3d94bad6db92fc2927c2e3c081ae8303e209e

Suggested affected range: praisonai >= 4.5.112, <= 4.6.58.

The lower bound is conservative and based on sampled tags. Maintainers should confirm the exact introduction point before publishing a final range.

Root cause

The installed entrypoint routes registered Typer commands before falling back to the legacy dispatcher:

if first_cmd in _get_typer_commands():
    _run_typer(argv)
else:
    _run_legacy(argv)

cli/app.py registers commands.recipe as the recipe Typer command:

from .commands.recipe import app as recipe_app
...
app.add_typer(recipe_app, name="recipe", help="Recipe management")

The deprecated Typer recipe serve implementation accepts a remote host, defaults CORS to *, and only enables authentication when --api-key is explicitly provided:

host: str = typer.Option("127.0.0.1", "--host", "-h", ...)
api_key: str = typer.Option(None, "--api-key", ...)
cors: str = typer.Option("*", "--cors", ...)
admin: bool = typer.Option(False, "--admin", ...)
...
serve_config = {}
...
if api_key:
    serve_config["api_key"] = api_key
    serve_config["auth"] = "api-key"
if cors:
    serve_config["cors_origins"] = cors
if admin:
    serve_config["enable_admin"] = True
...
serve(host=host, port=port, reload=reload, config=serve_config, workers=workers)

There is no equivalent to the hardened non-localhost guard in the legacy feature handler:

if host != "127.0.0.1" and host != "localhost" and auth == "none":
    self._print_error("Auth required for non-localhost binding. Use --auth api-key or --auth jwt")
    return self.EXIT_POLICY_DENIED

The Recipe server only installs auth middleware when config["auth"] is set:

auth_type = config.get("auth")
if auth_type and auth_type != "none":
    auth_middleware = create_auth_middleware(...)
    if auth_middleware:
        middleware.append(Middleware(auth_middleware))

On current v4.6.58, the…

Record
PYSEC-2026-3502
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
praisonai
PyPI
4.5.112 to 4.6.58
4.6.59
praisonai
PyPI
4.5.112 up to 4.6.59, plus listed versions
4.5.1134.5.1144.5.1154.5.1174.5.118
Show 45 moreShow less
4.5.1194.5.1204.5.1214.5.1224.5.1234.5.1244.5.1254.5.1264.5.1274.5.1284.5.1294.5.1304.5.1314.5.1324.5.1334.5.1344.5.1354.5.1364.5.1374.5.1394.5.1404.5.1434.5.1444.5.1454.5.1494.6.104.6.114.6.124.6.134.6.144.6.154.6.164.6.184.6.194.6.204.6.214.6.224.6.234.6.244.6.254.6.264.6.274.6.284.6.294.6.30
4.6.59

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-56836 is a high vulnerability (CVSS 8.2) in Mervinpraison Praisonai, published June 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.33%, the 26th percentile. Fixed in praisonai 4.6.59.

References

This page doesn't list everything

Left out here: 28 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open