The AgentOS server in the praisonai TypeScript/npm package ships an insecure default: it binds 0.0.0.0, sets no API key, and uses CORS * with credentials. The API-key middleware is only registered when an API key is configured, so the documented quickstart (new AgentOS({agents:[...]}).serve({port})) exposes, unauthenticated, GET /api/agents (which leaks agent names/roles/instructions, i.e. system prompts) and POST /api/chat (which invokes agents). Any network peer can read agent system prompts and drive the agent. Runtime-confirmed; severity High.
praisonai (npm / TypeScript). Files src/praisonai-ts/src/os/config.ts and src/praisonai-ts/src/os/agentos.ts (AgentOS).Path:
src/praisonai-ts/src/os/config.ts
Class/const:
DEFAULT_AGENTOS_CONFIG / mergeConfig
Snippet:
export const DEFAULT_AGENTOS_CONFIG = {
host: '0.0.0.0',
corsOrigins: ['*'],
apiKey: '',
// ...
};
// mergeConfig: apiKey = userConfig?.apiKey ?? process.env.PRAISONAI_AGENTOS_API_KEY ?? '';
Issue: defaults bind all interfaces, with an empty API key and wildcard CORS. apiKey stays empty unless the developer explicitly sets it.
Path:
src/praisonai-ts/src/os/agentos.ts
Function:
serve / _registerRoutes (Express app)
Snippet:
if (this.config.apiKey) { // auth middleware ONLY added when apiKey is set
app.use((req,res,next) => { /* 401 unless Bearer/x-auth-token matches */ });
}
// routes:
app.get(`${apiPrefix}/agents`, ...) // returns name/role/instructions
app.post(`${apiPrefix}/chat`, ...) // calls agent.chat(message)
Issue: the only auth gate is conditional on a non-empty apiKey. With the default empty key, no auth middleware is registered, and GET /api/agents (system-prompt disclosure) and POST /api/chat (agent invocation) are served to any network client. CORS sets Access-Control-Allow-Credentials: true with a wildcard origin.
apiKey/PRAISONAI_AGENTOS_API_KEY.GET /api/agents → receives agent instructions/system prompts.POST /api/chat → invokes the agent.There is no protection in the default config — the auth gate is skipped when apiKey is empty (the default), and the server binds all interfaces.
Unauthenticated network access to agent metadata + invocation. This is the CVE-2026-44338 anti-pattern recurring in the TS package, and worse (0.0.0.0 is the default).
Real AgentOS from src/praisonai-ts run via ts-node in a node container with default config (stub agent, no LLM needed). 127.0.0.1:18000. Runnable assets: PraisonAI-Runtime-Repro\runtime-files\ (docker-compose.agentos.yml).
PRAI-01-01-AgentOS-Agents-NoAuth: GET /api/agents (no Authorization) → 127.0.0.1:18000.PRAI-01-02-AgentOS-Chat-NoAuth: POST /api/chat {"message":"hello from attacker"} (no Authorization).Non-loopback exposure should require authentication; agent instructions should not be disclosed unauthenticated.
GET /api/agents → 200, leaks "instructions":"SYSTEM PROMPT SECRET ... PRAISONAI_INTERNAL_SECRET_CANARY_7f3a91"; response header Access-Control-Allow-Credentials: true.POST /api/chat → 200, agent invoked ("response":"...PRAISONAI_AGENTOS_CANARY_7f3a91...").Unauthenticated /api/agents leaks agent instructions
A GET request to /api/agents succeeds without an Authorization header. The response exposes agent metadata and instructions, including the canary system-prompt value.
Unauthenticated /api/chat invokes the agent
A POST request to /api/chat succeeds without an Authorization header. The response confirms that the attacker-controlled message was processed by the configured agent.
The attached archive contains the local Docker runtime used to reproduce the issue with controlled canary values only. It does not contain real secrets, third-party API keys, or production credentials.
Unauthenticated disclosure of agent configuration/system prompts; unauthenticated agent invocation; LLM cost abuse; possible tool abuse depending on the configured agent's tools; permissive CORS-with-credentials.
host to 127.0.0.1; require apiKey (fail closed) when binding non-loopback.corsOrigins to ['*'], especially with Access-Control-Allow-Credentials: true.instructions on an unauthenticated endpoint.{
"cwe_ids": [
"CWE-200",
"CWE-284",
"CWE-306"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-08T22:01:29Z",
"nvd_published_at": null,
"severity": "HIGH"
}