Every CVE Search/ Get API key

CVE-2026-55837

dbt-mcp: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

6.8 MediumFix available

dbt-mcp is a Model Context Protocol server for interacting with dbt. Prior to 1.20.0, the local OAuth helper in src/dbt_mcp/oauth/fastapi_app.py exposes GET /dbt_platform_context without authentication or Host validation after a user completes the dbt Platform OAuth flow. The endpoint returns the full DbtPlatformContext, including access_token and refresh_token values persisted by the context manager, to any process that can reach 127.0.0.1:6785. The absence of TrustedHostMiddleware allows a remote attacker to use DNS rebinding against a victim's browser because the helper accepts arbitrary Host headers, while a co-located process can request the endpoint directly. The stolen tokens provide immediate dbt Platform API access as the victim and persistent access through the refresh token, allowing access to or modification of projects, jobs, environment secrets, and related account data. This issue is fixed in version 1.20.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.27%Up 0.1 points since Sep 15, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.8

dbt-mcp: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

dbt-mcp is a Model Context Protocol server for interacting with dbt. Prior to 1.20.0, the local OAuth helper in src/dbt_mcp/oauth/fastapi_app.py exposes GET /dbt_platform_context without authentication or Host validation after a user completes the dbt Platform OAuth flow. The endpoint returns the full DbtPlatformContext, including access_token and refresh_token values persisted by the context manager, to any process that can reach 127.0.0.1:6785. The absence of TrustedHostMiddleware allows a remote attacker to use DNS rebinding against a victim's browser because the helper accepts arbitrary Host headers, while a co-located process can request the endpoint directly. The stolen tokens provide immediate dbt Platform API access as the victim and persistent access through the refresh token, allowing access to or modification of projects, jobs, environment secrets, and related account data. This issue is fixed in version 1.20.0.

Record
CVE-2026-55837
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-200, CWE-306, CWE-346
Updated
2026-11-02
EUVDEUVD-2026-77639 6.8

dbt-mcp is a Model Context Protocol server for interacting with dbt. Prior to 1.20.0, the local OAuth helper in src/dbt_mcp/oauth/fastapi_app.py exposes GET /dbt_platform_context without authentication or Host validation after a user completes the dbt Platform OAuth flow. The endpoint returns the full DbtPlatformContext, including access_token and refresh_token values persisted by the context manager, to any process that can reach 127.0.0.1:6785. The absence of TrustedHostMiddleware allows a remote attacker to use DNS rebinding against a victim's browser because the helper accepts arbitrary Host headers, while a co-located process can request the endpoint directly. The stolen tokens provide immediate dbt Platform API access as the victim and persistent access through the refresh token, allowing access to or modification of projects, jobs, environment secrets, and related account data. This issue is fixed in version 1.20.0.

Record
EUVD-2026-77639
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-jr33-mw75-7j8f 6.8

dbt MCP Server: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Summary

The local OAuth helper FastAPI server bundled with dbt-mcp exposes the GET /dbt_platform_context endpoint without any form of authentication or host-origin validation. After a user completes the OAuth login flow against dbt Cloud (cloud.getdbt.com), the endpoint returns the full DbtPlatformContext object — including the victim's access_token and refresh_token for the dbt Platform API — verbatim to any caller that can reach 127.0.0.1:6785. An attacker who can direct the victim's browser to the helper origin via DNS rebinding, or who has co-located process access on the same host, can silently exfiltrate both tokens. The stolen bearer token grants full dbt Cloud API access as the victim; the refresh token enables persistent access beyond the original token's expiry. CVSS Base Score: 8.0 (High).

Details

During the OAuth login flow, dbt-mcp launches an embedded FastAPI server (the "OAuth helper") bound to 127.0.0.1 starting on port 6785 (configured at src/dbt_mcp/config/credentials.py:34, OAUTH_REDIRECT_STARTING_PORT = 6785). After the OAuth callback is handled, the helper persists the full token context to disk and continues serving requests.

Data flow from source to sink:

  1. Source — src/dbt_mcp/oauth/fastapi_app.py:106: The OAuth callback receives token_response from the dbt Platform authorization server.
  2. src/dbt_mcp/oauth/dbt_platform.py:60: AccessTokenResponse(**token_response) stores access_token and refresh_token as plaintext fields.
  3. src/dbt_mcp/oauth/dbt_platform.py:64–69: The AccessTokenResponse is embedded inside DecodedAccessToken, which is in turn embedded inside DbtPlatformContext.
  4. src/dbt_mcp/oauth/fastapi_app.py:114: The fully token-bearing DbtPlatformContext object is passed to context_manager for persistence.
  5. Persistence sink — src/dbt_mcp/oauth/context_manager.py:63–64: yaml.dump(context.model_dump()) serializes the entire model — including tokens — to a YAML file on disk.
  6. HTTP sink — src/dbt_mcp/oauth/fastapi_app.py:162–165: The GET /dbt_platform_context route reads the YAML file back and returns the raw DbtPlatformContext object with no redaction.
# src/dbt_mcp/oauth/fastapi_app.py:162-165
@app.get("/dbt_platform_context")
def get_dbt_platform_context() -> DbtPlatformContext:
    logger.info("Selected project received")
    return dbt_platform_context_manager.read_context() or DbtPlatformContext()
# src/dbt_mcp/oauth/dbt_platform.py:8-14
class AccessTokenResponse(BaseModel):
    access_token: str
    refresh_token: str
    ...

class DbtPlatformContext(BaseModel):
    decoded_access_token: DecodedAccessToken | None = None
    ...

Missing protections (confirmed by grep):

  • No TrustedHostMiddleware — the server accepts requests with arbitrary Host headers, enabling DNS rebinding.
  • No CORSMiddleware — no cross-origin restrictions on which sites can read the response.
  • No CSRF protection, no session nonce, no Origin header validation.
  • The route has no FastAPI Depends() security dependency.

A grep -Rni "TrustedHostMiddleware\|CORSMiddleware\|csrf\|origin" across the OAuth FastAPI application returns no results.

Recommended remediation:

--- a/src/dbt_mcp/oauth/fastapi_app.py
+++ b/src/dbt_mcp/oauth/fastapi_app.py
+from starlette.middleware.trustedhost import TrustedHostMiddleware
+
+def _redact_context(context: DbtPlatformContext | None) -> DbtPlatformContext:
+    if context is None:
+        return DbtPlatformContext()
+    return context.model_copy(update={"decoded_access_token": None})

     app = FastAPI()
+    app.add_middleware(
+        TrustedHostMiddleware,
+        allowed_hosts=["localhost", "127.0.0.1"],
+    )

     @app.get("/dbt_platform_context")
     def get_dbt_platform_context() -> DbtPlatformContext:
        …
Record
GHSA-jr33-mw75-7j8f
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-200, CWE-306, CWE-346
Updated
2026-11-02
NVD 6.8

dbt-mcp is a Model Context Protocol server for interacting with dbt. Prior to 1.20.0, the local OAuth helper in src/dbt_mcp/oauth/fastapi_app.py exposes GET /dbt_platform_context without authentication or Host validation after a user completes the dbt Platform OAuth flow. The endpoint returns the full DbtPlatformContext, including access_token and refresh_token values persisted by the context manager, to any process that can reach 127.0.0.1:6785. The absence of TrustedHostMiddleware allows a remote attacker to use DNS rebinding against a victim's browser because the helper accepts arbitrary Host headers, while a co-located process can request the endpoint directly. The stolen tokens provide immediate dbt Platform API access as the victim and persistent access through the refresh token, allowing access to or modification of projects, jobs, environment secrets, and related account data. This issue is fixed in version 1.20.0.

Record
CVE-2026-55837
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-200, CWE-306, CWE-346
Updated
2026-11-02
OSV 6.8

dbt-mcp: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

dbt-mcp is a Model Context Protocol server for interacting with dbt. Prior to 1.20.0, the local OAuth helper in src/dbt_mcp/oauth/fastapi_app.py exposes GET /dbt_platform_context without authentication or Host validation after a user completes the dbt Platform OAuth flow. The endpoint returns the full DbtPlatformContext, including access_token and refresh_token values persisted by the context manager, to any process that can reach 127.0.0.1:6785. The absence of TrustedHostMiddleware allows a remote attacker to use DNS rebinding against a victim's browser because the helper accepts arbitrary Host headers, while a co-located process can request the endpoint directly. The stolen tokens provide immediate dbt Platform API access as the victim and persistent access through the refresh token, allowing access to or modification of projects, jobs, environment secrets, and related account data. This issue is fixed in version 1.20.0.

Record
CVE-2026-55837
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-200, CWE-306, CWE-346
Updated
2026-11-02
OSVGHSA-jr33-mw75-7j8f 6.8

dbt MCP Server: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Summary

The local OAuth helper FastAPI server bundled with dbt-mcp exposes the GET /dbt_platform_context endpoint without any form of authentication or host-origin validation. After a user completes the OAuth login flow against dbt Cloud (cloud.getdbt.com), the endpoint returns the full DbtPlatformContext object — including the victim's access_token and refresh_token for the dbt Platform API — verbatim to any caller that can reach 127.0.0.1:6785. An attacker who can direct the victim's browser to the helper origin via DNS rebinding, or who has co-located process access on the same host, can silently exfiltrate both tokens. The stolen bearer token grants full dbt Cloud API access as the victim; the refresh token enables persistent access beyond the original token's expiry. CVSS Base Score: 8.0 (High).

Details

During the OAuth login flow, dbt-mcp launches an embedded FastAPI server (the "OAuth helper") bound to 127.0.0.1 starting on port 6785 (configured at src/dbt_mcp/config/credentials.py:34, OAUTH_REDIRECT_STARTING_PORT = 6785). After the OAuth callback is handled, the helper persists the full token context to disk and continues serving requests.

Data flow from source to sink:

  1. Source — src/dbt_mcp/oauth/fastapi_app.py:106: The OAuth callback receives token_response from the dbt Platform authorization server.
  2. src/dbt_mcp/oauth/dbt_platform.py:60: AccessTokenResponse(**token_response) stores access_token and refresh_token as plaintext fields.
  3. src/dbt_mcp/oauth/dbt_platform.py:64–69: The AccessTokenResponse is embedded inside DecodedAccessToken, which is in turn embedded inside DbtPlatformContext.
  4. src/dbt_mcp/oauth/fastapi_app.py:114: The fully token-bearing DbtPlatformContext object is passed to context_manager for persistence.
  5. Persistence sink — src/dbt_mcp/oauth/context_manager.py:63–64: yaml.dump(context.model_dump()) serializes the entire model — including tokens — to a YAML file on disk.
  6. HTTP sink — src/dbt_mcp/oauth/fastapi_app.py:162–165: The GET /dbt_platform_context route reads the YAML file back and returns the raw DbtPlatformContext object with no redaction.
# src/dbt_mcp/oauth/fastapi_app.py:162-165
@app.get("/dbt_platform_context")
def get_dbt_platform_context() -> DbtPlatformContext:
    logger.info("Selected project received")
    return dbt_platform_context_manager.read_context() or DbtPlatformContext()
# src/dbt_mcp/oauth/dbt_platform.py:8-14
class AccessTokenResponse(BaseModel):
    access_token: str
    refresh_token: str
    ...

class DbtPlatformContext(BaseModel):
    decoded_access_token: DecodedAccessToken | None = None
    ...

Missing protections (confirmed by grep):

  • No TrustedHostMiddleware — the server accepts requests with arbitrary Host headers, enabling DNS rebinding.
  • No CORSMiddleware — no cross-origin restrictions on which sites can read the response.
  • No CSRF protection, no session nonce, no Origin header validation.
  • The route has no FastAPI Depends() security dependency.

A grep -Rni "TrustedHostMiddleware\|CORSMiddleware\|csrf\|origin" across the OAuth FastAPI application returns no results.

Recommended remediation:

--- a/src/dbt_mcp/oauth/fastapi_app.py
+++ b/src/dbt_mcp/oauth/fastapi_app.py
+from starlette.middleware.trustedhost import TrustedHostMiddleware
+
+def _redact_context(context: DbtPlatformContext | None) -> DbtPlatformContext:
+    if context is None:
+        return DbtPlatformContext()
+    return context.model_copy(update={"decoded_access_token": None})

     app = FastAPI()
+    app.add_middleware(
+        TrustedHostMiddleware,
+        allowed_hosts=["localhost", "127.0.0.1"],
+    )

     @app.get("/dbt_platform_context")
     def get_dbt_platform_context() -> DbtPlatformContext:
        …
Record
GHSA-jr33-mw75-7j8f
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-200, CWE-306, CWE-346
Updated
2026-11-02
OSVPYSEC-2026-2443 6.8

dbt MCP Server: Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Unauthenticated OAuth Context Endpoint Leaks dbt Platform Tokens

Summary

The local OAuth helper FastAPI server bundled with dbt-mcp exposes the GET /dbt_platform_context endpoint without any form of authentication or host-origin validation. After a user completes the OAuth login flow against dbt Cloud (cloud.getdbt.com), the endpoint returns the full DbtPlatformContext object — including the victim's access_token and refresh_token for the dbt Platform API — verbatim to any caller that can reach 127.0.0.1:6785. An attacker who can direct the victim's browser to the helper origin via DNS rebinding, or who has co-located process access on the same host, can silently exfiltrate both tokens. The stolen bearer token grants full dbt Cloud API access as the victim; the refresh token enables persistent access beyond the original token's expiry. CVSS Base Score: 8.0 (High).

Details

During the OAuth login flow, dbt-mcp launches an embedded FastAPI server (the "OAuth helper") bound to 127.0.0.1 starting on port 6785 (configured at src/dbt_mcp/config/credentials.py:34, OAUTH_REDIRECT_STARTING_PORT = 6785). After the OAuth callback is handled, the helper persists the full token context to disk and continues serving requests.

Data flow from source to sink:

  1. Source — src/dbt_mcp/oauth/fastapi_app.py:106: The OAuth callback receives token_response from the dbt Platform authorization server.
  2. src/dbt_mcp/oauth/dbt_platform.py:60: AccessTokenResponse(**token_response) stores access_token and refresh_token as plaintext fields.
  3. src/dbt_mcp/oauth/dbt_platform.py:64–69: The AccessTokenResponse is embedded inside DecodedAccessToken, which is in turn embedded inside DbtPlatformContext.
  4. src/dbt_mcp/oauth/fastapi_app.py:114: The fully token-bearing DbtPlatformContext object is passed to context_manager for persistence.
  5. Persistence sink — src/dbt_mcp/oauth/context_manager.py:63–64: yaml.dump(context.model_dump()) serializes the entire model — including tokens — to a YAML file on disk.
  6. HTTP sink — src/dbt_mcp/oauth/fastapi_app.py:162–165: The GET /dbt_platform_context route reads the YAML file back and returns the raw DbtPlatformContext object with no redaction.
# src/dbt_mcp/oauth/fastapi_app.py:162-165
@app.get("/dbt_platform_context")
def get_dbt_platform_context() -> DbtPlatformContext:
    logger.info("Selected project received")
    return dbt_platform_context_manager.read_context() or DbtPlatformContext()
# src/dbt_mcp/oauth/dbt_platform.py:8-14
class AccessTokenResponse(BaseModel):
    access_token: str
    refresh_token: str
    ...

class DbtPlatformContext(BaseModel):
    decoded_access_token: DecodedAccessToken | None = None
    ...

Missing protections (confirmed by grep):

  • No TrustedHostMiddleware — the server accepts requests with arbitrary Host headers, enabling DNS rebinding.
  • No CORSMiddleware — no cross-origin restrictions on which sites can read the response.
  • No CSRF protection, no session nonce, no Origin header validation.
  • The route has no FastAPI Depends() security dependency.

A grep -Rni "TrustedHostMiddleware\|CORSMiddleware\|csrf\|origin" across the OAuth FastAPI application returns no results.

Recommended remediation:

--- a/src/dbt_mcp/oauth/fastapi_app.py
+++ b/src/dbt_mcp/oauth/fastapi_app.py
+from starlette.middleware.trustedhost import TrustedHostMiddleware
+
+def _redact_context(context: DbtPlatformContext | None) -> DbtPlatformContext:
+    if context is None:
+        return DbtPlatformContext()
+    return context.model_copy(update={"decoded_access_token": None})

     app = FastAPI()
+    app.add_middleware(
+        TrustedHostMiddleware,
+        allowed_hosts=["localhost", "127.0.0.1"],
+    )

     @app.get("/dbt_platform_context")
     def get_dbt_platform_context() -> DbtPlatformContext:
        …
Record
PYSEC-2026-2443
CVSS 3.1
6.8 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
dbt-mcp
PyPI
before 1.20.0
1.20.0
dbt-mcp
PyPI
before 1.20.0, plus listed versions
0.0.1a10.1.00.1.10.1.20.1.2rc1
Show 45 moreShow less
0.1.2rc20.1.30.10.00.10.10.10.20.10.30.2.10.2.100.2.110.2.120.2.130.2.140.2.150.2.160.2.170.2.180.2.190.2.200.2.30.2.40.2.50.2.60.2.70.2.80.2.90.3.00.4.00.4.10.4.20.5.00.6.00.6.10.7.00.8.00.8.10.8.20.8.30.8.40.9.00.9.11.0.01.1.01.10.01.11.01.12.0
1.20.0

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-55837 is a medium vulnerability (CVSS 6.8) in Dbt-labs Dbt-mcp, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in dbt-mcp 1.20.0.

References

This page doesn't list everything

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

MoveEnter Open