GHSA-4qq2-2j2x-x62c: npm PraisonAI MCPSecurity Basic/OAuth authentication policies accept invalid credentials without validation
SummaryThe published npm package `praisonai` exports an `MCPSecurity` helper described in source as:Its `AuthMethod` type advertises five authentication methods:The authentication-policy evaluator, however, only validates credentials for `api-key` and `bearer`:For `basic` and `oauth`, any non-empty `Authorization` header skips the supplied `validate` callback and returns allowed. A local PoV configures `auth.validate` to always return `false`; invalid `api-key` and `bearer` credentials are rejected, while invalid `basic` and `oauth` credentials are accepted without calling the validator.This is a protection-mechanism failure in the exported npm MCP security helper. It is distinct from the separate issue that the npm `MCPServer` HTTP transport does not enforce authentication by default.Technical Details`SecurityPolicy.auth` accepts both a method and a validator:`extractToken()` parses both Bearer and Basic headers:But `evaluatePolicy()` only calls `policy.auth.validate()` for two methods:There is no validation branch for `basic` or `oauth`. After extracting any non-empty token, those methods fall through to the success return:`check()` then ignores successful authentication context and returns a generic allowed result:That context propagation issue is secondary. The security-relevant flaw is that invalid Basic/OAuth credentials are allowed at all.Why This Is Not Intended BehaviorThis is not a claim that every `MCPSecurity` user must choose Basic or OAuth. The issue is that the API explicitly exposes those methods as authentication methods and accepts a validator callback for the policy, but the implementation does not call the validator for those methods.The control cases prove the intended security behavior:Missing Basic credentials are denied as `Authentication required`.Invalid `api-key` credentials are denied as `Invalid credentials`.Invalid `bearer` credentials are denied as `Invalid credentials`.The only difference in the vulnerable cases is the selected advertised method. Invalid Basic/OAuth credentials should not become authenticated merely because the method is not listed in the two-method validation branch.This also matches MCP authorization guidance. MCP servers acting as resource servers must validate received access tokens; receiving a token is not proof that it is valid or intended for the server.PoVRun from a local reproduction checkout:The PoV:Installs `npm:praisonai@1.7.1` into a temporary project with scripts disabled.Imports `MCPSecurity` from the package root.Creates one `authenticate` policy per method.Supplies an `auth.validate` callback that always returns `false`.Sends invalid `api-key`, `bearer`, `basic`, and `oauth` credentials.Confirms the missing-header Basic control is still denied.Observed output summary from `evidence/pov-npm-1.7.1.json`:The PoV is local-only. It does not start a server, contact a third-party target, or use live credentials.PoCThe PoV section above contains the local reproduction command, input, and decisive output.ImpactA downstream application that uses `MCPSecurity` to protect an HTTP MCP transport, gateway, or equivalent tool/resource endpoint can believe it has enabled Basic or OAuth authentication while accepting any non-empty `Authorization` header.Depending on the protected MCP tools and resources, this can allow an unauthenticated network caller to:list protected tools or resources;call tools that were intended to require authentication;read protected MCP resources;trigger agent/workflow actions exposed behind the security helper; andbypass audit assumptions based on the configured validator.This report does not claim that npm PraisonAI wires `MCPSecurity` into the default `MCPServer.startHttp()` path. It is a library-level authentication bypass in an exported security component intended to protect MCP servers.SeveritySuggested severity: High.Rationale:`AV`: the affected helper is intended to protect MCP server requests and equivalent HTTP security checks.`AC`: a single non-empty Basic or OAuth-style Authorization header is sufficient when such a policy is configured.`PR`: the bypass grants access without valid credentials.`UI`: no maintainer or user interaction is required after deployment.`S`: impact is within the PraisonAI-hosting service and its exposed MCP resources/tools.`C`: protected MCP resources or tool outputs may be disclosed.`I`: protected tool calls may perform state-changing actions depending on the registered tools; the score is conservative because the vulnerable helper is library-level and deployment-dependent.`A`: the PoV does not demonstrate availability impact.If a deployment protects high-impact write or execution tools with `MCPSecurity`, maintainers may reasonably score integrity higher.Suggested FixMake authentication evaluation fail closed for every advertised method.Recommended:For `authenticate` policies, call `policy.auth.validate(token)` whenever it is provided, regardless of `auth.method`.If no validator is provided, only fall back to `validateApiKey()` for `api-key` when that behavior is explicitly intended.For `bearer` and `oauth`, require a validator or a server-side token validation implementation; otherwise deny with a configuration error.For `basic`, decode the Basic credential safely and pass the decoded username/password or raw credential to a validator; if no validator exists, deny.Treat unknown or unsupported methods as denied, not allowed.Return authenticated context from `check()` after a successful authenticate policy instead of replacing it with `{ authenticated: false }`.Add regression tests proving invalid credentials are rejected for `api-key`, `bearer`, `basic`, and `oauth`, and that each configured validator is called.Minimal fail-closed shape:Affected Package/VersionsRepository: `MervinPraison/PraisonAI`Ecosystem: `npm`Package: `praisonai`Component: TypeScript MCP security helper `src/praisonai-ts/src/mcp/security.ts`Published dist path: `node_modules/praisonai/dist/mcp/security.js`Latest npm package validated: `1.7.1`Current `origin/main` validated: `1ad58ca02975ff1398efeda694ea2ab78f20cf3e``src/praisonai-ts/package.json` at `origin/main`: `praisonai` `1.7.1`Suggested affected range:All published npm `1.x` versions were swept locally:`1.0.0` through `1.5.0`: the tested root export was unavailable or `MCPSecurity` was not exported as a constructor.`1.5.1`, `1.5.2`, `1.5.3`, `1.5.4`, `1.6.0`, `1.7.0`, and `1.7.1`: vulnerable.The package root re-exports this helper:Advisory HistoryVisible PraisonAI advisories and prior submissions were checked. The closest public advisory is `GHSA-98f9-fqg5-hvq5` / `CVE-2026-34953`, but that issue is distinct:`GHSA-98f9-fqg5-hvq5` affects the PyPI package and Python `OAuthManager.validate_token()`.This report affects the npm package and TypeScript `src/praisonai-ts/src/mcp/security.ts`.The prior issue accepts arbitrary Bearer tokens because an empty Python token store falls through to `True`.This issue accepts invalid Basic/OAuth credentials because the TypeScript validator callback is never called for those advertised methods.The affected ranges and patched surfaces are different.The earlier npm `MCPServer` report is also distinct: it covers missing auth in the HTTP transport by default. This report covers a fail-open branch in the separate exported `MCPSecurity` helper when users attempt to add Basic/OAuth authentication.
CVSS v3.1: 8.2