Skip to content

File tree

8 files changed

+41
-17
lines changed

8 files changed

+41
-17
lines changed

advisories/github-reviewed/2026/03/GHSA-5h2m-4q8j-pqpj/GHSA-5h2m-4q8j-pqpj.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-5h2m-4q8j-pqpj",
4-
"modified": "2026-03-16T15:14:55Z",
4+
"modified": "2026-03-16T21:55:10Z",
55
"published": "2026-03-16T15:14:55Z",
66
"aliases": [
77
"CVE-2025-69196"
88
],
99
"summary": "FastMCP OAuth Proxy token reuse across MCP servers",
10-
"details": "While testing the OAuth Proxy implementation, it was noticed that the server does not properly respect the `resource` parameter submitted by the client in the authorization and token request. Instead of issuing the token explicitly for this MCP server, the token is issued for the `base_url` passed to the `OAuthProxy` during initialization. \n\n**Affected File:**\n*https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L828*\n\n**Affected Code:**\n```python\nself._jwt_issuer: JWTIssuer = JWTIssuer(\n issuer=str(self.base_url),\n audience=f\"{str(self.base_url).rstrip('/')}/mcp\",\n signing_key=jwt_signing_key,\n)\n```\n\nSince the issued access and refresh tokens do not include information about the resource the token was issued for, it is impossible for the MCP server to properly verify whether the token was issued for it, hence violating the requirement of doing so demanded by the [specification](https://mcp.mintlify.app/specification/2025-11-25/basic/authorization#token-audience-binding-and-validation). Being able to verify whether the token was issued for the target MCP server enforces the protection offered by the, per MCP specification mandatory, Protected Resource Metadata OAuth extension.\n\nTherefore, this misconfiguration exposes all MCP server setups using the FastMCP OAuth Proxy to an attack where an adversary creates a malicious MCP server that advertises the benign OAuth Proxy authorization server as its own authorization server. Once a victim completes an OAuth flow with this malicious MCP server, authenticating against the AS, the adversary can extract the token received at the malicious MCP server and use it to access other MCP servers (the benign ones) that also use the same AS, including the tools and resources they expose.\n\n**Steps to reproduce:**\n1. Extract the provided [PoC environment](https://github.com/user-attachments/files/23839983/improper_resource_validation_fastmcp.tgz).\n2. Enter the *client_id* and *client_secret* of a GitHub App you control into the `mcp-server-proxy.py` script.\n3. Start the benign MCP server using an OAuth Proxy (in this case the *GitHubProvider*): `python3 mcp-server-proxy.py`.\n4. Start the malicious AS: `python3 mal_auth_server.py`.\n5. Start the malicious MCP server: `python3 attacker_server.py`.\n6. Connect the client to the malicious MCP server: `python3 client.py`.\n7. Complete the OAuth flow.\n8. Observe in the logs of the malicious MCP server that the request to the benign MCP server with the stolen token returned a 200 status code.\n\n## Impact\n\nThis vulnerability allows an adversary to steal a victim’s authentication material for a benign MCP server using the FastMCP OAuth Proxy. The severity of this issue was decreased to _Medium_ due to the consent screen showing the name of the MCP server the OAuth Proxy was intended for. However, a victim might not see it or get otherwise convinced by the attacker to ignore it, and overall this does not act as a proper mitigation for this issue.\n\n## Mitigation\n\nTo mitigate this vulnerability, it is recommended to issue tokens specifically for the MCP server submitted in the authorization URL’s `resource` GET parameter. In this way, the receiving MCP server will be able to properly verify that the token was indeed issued for it, allowing it to reject tokens stolen by an attack like the one demonstrated above.",
10+
"details": "While testing the OAuth Proxy implementation, it was noticed that the server does not properly respect the `resource` parameter submitted by the client in the authorization and token request. Instead of issuing the token explicitly for this MCP server, the token is issued for the `base_url` passed to the `OAuthProxy` during initialization. \n\n**Affected File:**\n*https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L828*\n\n**Affected Code:**\n```python\nself._jwt_issuer: JWTIssuer = JWTIssuer(\n issuer=str(self.base_url),\n audience=f\"{str(self.base_url).rstrip('/')}/mcp\",\n signing_key=jwt_signing_key,\n)\n```\n\nSince the issued access and refresh tokens do not include information about the resource the token was issued for, it is impossible for the MCP server to properly verify whether the token was issued for it, hence violating the requirement of doing so demanded by the [specification](https://mcp.mintlify.app/specification/2025-11-25/basic/authorization#token-audience-binding-and-validation). Being able to verify whether the token was issued for the target MCP server enforces the protections offered by the steps proposed by the specification and the Resource Indicators OAuth extension.\n\nTherefore, this misconfiguration exposes all MCP server setups using the FastMCP OAuth Proxy to an attack where an adversary creates a malicious MCP server that advertises the benign OAuth Proxy authorization server as its own authorization server. Once a victim completes an OAuth flow with this malicious MCP server, authenticating against the AS, the adversary can extract the token received at the malicious MCP server and use it to access other MCP servers (the benign ones) that also use the same AS, including the tools and resources they expose.\n\n**Steps to reproduce:**\n1. Extract the provided [PoC environment](https://github.com/user-attachments/files/23839983/improper_resource_validation_fastmcp.tgz).\n2. Enter the *client_id* and *client_secret* of a GitHub App you control into the `mcp-server-proxy.py` script.\n3. Start the benign MCP server using an OAuth Proxy (in this case the *GitHubProvider*): `python3 mcp-server-proxy.py`.\n4. Start the malicious AS: `python3 mal_auth_server.py`.\n5. Start the malicious MCP server: `python3 attacker_server.py`.\n6. Connect the client to the malicious MCP server: `python3 client.py`.\n7. Complete the OAuth flow.\n8. Observe in the logs of the malicious MCP server that the request to the benign MCP server with the stolen token returned a 200 status code.\n\n## Impact\n\nThis vulnerability allows an adversary to steal a victim’s authentication material for a benign MCP server using the FastMCP OAuth Proxy. The severity of this issue was decreased to _Medium_ due to the consent screen showing the name of the MCP server the OAuth Proxy was intended for. However, a victim might not see it or get otherwise convinced by the attacker to ignore it, and overall this does not act as a proper mitigation for this issue.\n\n## Mitigation\n\nTo mitigate this vulnerability, it is recommended to issue tokens specifically for the MCP server submitted in the authorization URL’s `resource` GET parameter. In this way, the receiving MCP server will be able to properly verify that the token was indeed issued for it, allowing it to reject tokens stolen by an attack like the one demonstrated above.",
1111
"severity": [
1212
{
1313
"type": "CVSS_V4",
@@ -40,6 +40,10 @@
4040
"type": "WEB",
4141
"url": "https://github.com/PrefectHQ/fastmcp/security/advisories/GHSA-5h2m-4q8j-pqpj"
4242
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-69196"
46+
},
4347
{
4448
"type": "PACKAGE",
4549
"url": "https://github.com/PrefectHQ/fastmcp"
@@ -52,6 +56,6 @@
5256
"severity": "HIGH",
5357
"github_reviewed": true,
5458
"github_reviewed_at": "2026-03-16T15:14:55Z",
55-
"nvd_published_at": null
59+
"nvd_published_at": "2026-03-16T19:16:14Z"
5660
}
5761
}

advisories/github-reviewed/2026/03/GHSA-7432-952r-cw78/GHSA-7432-952r-cw78.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-7432-952r-cw78",
4-
"modified": "2026-03-16T15:17:28Z",
4+
"modified": "2026-03-16T21:54:05Z",
55
"published": "2026-03-16T15:17:28Z",
66
"aliases": [
77
"CVE-2026-28490"
@@ -43,6 +43,10 @@
4343
"type": "WEB",
4444
"url": "https://github.com/authlib/authlib/security/advisories/GHSA-7432-952r-cw78"
4545
},
46+
{
47+
"type": "ADVISORY",
48+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28490"
49+
},
4650
{
4751
"type": "WEB",
4852
"url": "https://github.com/authlib/authlib/commit/48b345f29f6c459f11c6a40162b6c0b742ef2e22"
@@ -64,6 +68,6 @@
6468
"severity": "HIGH",
6569
"github_reviewed": true,
6670
"github_reviewed_at": "2026-03-16T15:17:28Z",
67-
"nvd_published_at": null
71+
"nvd_published_at": "2026-03-16T18:16:07Z"
6872
}
6973
}

advisories/github-reviewed/2026/03/GHSA-f7cq-gvh6-qr25/GHSA-f7cq-gvh6-qr25.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-f7cq-gvh6-qr25",
4-
"modified": "2026-03-16T20:46:48Z",
4+
"modified": "2026-03-16T21:55:37Z",
55
"published": "2026-03-16T20:46:48Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-32771"
8+
],
79
"summary": "Monitoring is vulnerable to Archive Slip due to missing checks in sanitization",
810
"details": "The `sanitizeArchivePath` function in `pkg/extract/extract.go` (lines 248–254) is vulnerable to a path traversal bypass due to a missing trailing path separator in the `strings.HasPrefix` check. A crafted tar archive can write files outside the intended destination directory when using the `extractor` CLI tool or the `extract.DumpOTelCollector` library function.\n\n## Vulnerable Code\n\nFile: `pkg/extract/extract.go`, lines 248–254\n\n```go\nfunc sanitizeArchivePath(d, t string) (v string, err error) {\n v = filepath.Join(d, t)\n if strings.HasPrefix(v, filepath.Clean(d)) { // ← missing trailing separator\n return v, nil\n }\n return \"\", fmt.Errorf(\"filepath is tainted: %s\", t)\n}\n```\n\nThe function is called at line 219 inside `untar`, which is invoked by `copyFromPod` (line 205) during the Cold Extract data dump workflow.\n\n## Root Cause\n\n`strings.HasPrefix(v, filepath.Clean(d))` does not append a trailing `/` to the directory prefix, causing a **directory name prefix collision**. If the destination is `/home/user/extract-output` and a tar entry is named `../extract-outputevil/pwned`, the joined path `/home/user/extract-outputevil/pwned` passes the prefix check — it starts with `/home/user/extract-output` — even though it is entirely outside the intended directory.\n\n## Steps to Reproduce\n\n1. **Deploy the monitoring stack** with `ColdExtract: true`. The OTEL Collector begins writing signal data (`otel_traces`, `otel_metrics`, `otel_logs`) to the shared PVC.\n\n2. **Place the PoC tar on the PVC.** Any pod with write access to the `ReadWriteMany` PVC (or the compromised OTEL Collector itself) copies a `poc-path-traversal.tar` into the `/data/collector` mount path. The archive contains three real-looking OTLP telemetry files alongside two crafted entries with path-traversal names.\n\n3. **Run the extractor against the namespace:**\n\n ```\n extractor \\\n --namespace monitoring \\\n --pvc-name <signals-pvc-name> \\\n --directory /home/user/extract-output\n ```\n\n4. **Observe the bypass.** `untar` processes the tar stream. For the malicious entries:\n\n ```\n // entry name: ../extract-outputevil/poc-proof.txt\n filepath.Join(\"/home/user/extract-output\", \"../extract-outputevil/poc-proof.txt\")\n => \"/home/user/extract-outputevil/poc-proof.txt\"\n\n strings.HasPrefix(\"/home/user/extract-outputevil/poc-proof.txt\",\n \"/home/user/extract-output\")\n => true // BUG: prefix collision; file lands OUTSIDE target dir\n ```\n\n Both malicious entries are written outside `/home/user/extract-output/`. The three legitimate OTLP files land correctly inside it.\n\n## Impact\n\nSuccessful exploitation gives an attacker arbitrary file write on the machine running the extractor. Real-world primitives include:\n\n- Overwriting `~/.bashrc` / `~/.zshrc` / `~/.profile` for RCE on next shell login\n- Appending to `~/.ssh/authorized_keys` for persistent SSH backdoor\n- Dropping a malicious entry into `~/.kube/config` to hijack cluster access\n- Writing crontab entries for persistent scheduled execution\n\nThe attack surface is widened by the default `ReadWriteMany` PVC access mode, which means any pod in the cluster with the PVC mounted can inject the payload — not just the OTEL Collector itself.",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-hxm7-9q36-c77f/GHSA-hxm7-9q36-c77f.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-hxm7-9q36-c77f",
4-
"modified": "2026-03-16T20:47:15Z",
4+
"modified": "2026-03-16T21:55:30Z",
55
"published": "2026-03-16T20:47:15Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-32769"
8+
],
79
"summary": "Fullchain's Invalid NetworkPolicy enables a malicious actor to pivot into another namespace",
810
"details": "### Impact\n\nDue to a mis-written NetworkPolicy, a malicious actor can pivot from a subverted application to any Pod out of the origin namespace.\nThis breaks the security-by-default property expected as part of the deployment program, leading to a potential lateral movement.\n\n### Patch\n\nRemoving the `inter-ns` NetworkPolicy patches the vulnerability. If updates are not possible in production environments, we recommend to manually delete it and update as soon as possible.\n\n### Workaround\n\nGiven your context, delete the failing network policy that should be prefixed by `inter-ns-` in the target namespace.\nYou can use the following to delete all matching network policy. If unsure of the outcome, please do it manually.\n\n```bash\nfor ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\\n' | grep '^ns-'); do\n kubectl -n \"$ns\" get networkpolicy -o name \\\n | grep '^networkpolicy.networking.k8s.io/inter-ns-' \\\n | xargs -r kubectl -n \"$ns\" delete\ndone\n```",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-m344-f55w-2m6j/GHSA-m344-f55w-2m6j.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-m344-f55w-2m6j",
4-
"modified": "2026-03-16T16:15:06Z",
4+
"modified": "2026-03-16T21:54:15Z",
55
"published": "2026-03-16T16:15:06Z",
66
"aliases": [
77
"CVE-2026-28498"
@@ -43,6 +43,10 @@
4343
"type": "WEB",
4444
"url": "https://github.com/authlib/authlib/security/advisories/GHSA-m344-f55w-2m6j"
4545
},
46+
{
47+
"type": "ADVISORY",
48+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28498"
49+
},
4650
{
4751
"type": "WEB",
4852
"url": "https://github.com/authlib/authlib/commit/b9bb2b25bf8b7e01512d847a95c1749646eaa72b"
@@ -64,6 +68,6 @@
6468
"severity": "HIGH",
6569
"github_reviewed": true,
6670
"github_reviewed_at": "2026-03-16T16:15:06Z",
67-
"nvd_published_at": null
71+
"nvd_published_at": "2026-03-16T18:16:07Z"
6872
}
6973
}

advisories/github-reviewed/2026/03/GHSA-mw24-f3xh-j3qv/GHSA-mw24-f3xh-j3qv.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-mw24-f3xh-j3qv",
4-
"modified": "2026-03-16T20:45:34Z",
4+
"modified": "2026-03-16T21:55:24Z",
55
"published": "2026-03-16T20:45:34Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-32768"
8+
],
79
"summary": "Chall-Manager's invalid NetworkPolicy enables a malicious actor to pivot into another namespace",
810
"details": "### Impact\n\nDue to a mis-written NetworkPolicy, a malicious actor can pivot from an instance to any Pod out of the origin namespace.\nThis breaks the security-by-default property expected as part of the deployment program, leading to a potential lateral movement.\nIn the specific case of `sdk/kubernetes.Kompose` it does not isolate the instances.\n\n### Patch\n\nRemoving the `inter-ns` NetworkPolicy patches the vulnerability. If updates are not possible in production environments, we recommend to manually delete it and update as soon as possible.\n\n### Workaround\n\nGiven your context, delete the failing network policy that should be prefixed by `inter-ns-` in the target namespace.\nYou can use the following to delete all matching network policy. If unsure of the outcome, please do it manually.\n\n```bash\nfor ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\\n' | grep '^cm-target-'); do\n kubectl -n \"$ns\" get networkpolicy -o name \\\n | grep '^networkpolicy.networking.k8s.io/inter-ns-' \\\n | xargs -r kubectl -n \"$ns\" delete\ndone\n```",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-p799-g7vv-f279/GHSA-p799-g7vv-f279.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-p799-g7vv-f279",
4-
"modified": "2026-03-16T20:47:03Z",
4+
"modified": "2026-03-16T21:55:45Z",
55
"published": "2026-03-16T20:47:02Z",
6-
"aliases": [],
6+
"aliases": [
7+
"CVE-2026-32805"
8+
],
79
"summary": " Romeo is vulnerable to Archive Slip due to missing checks in sanitization",
810
"details": "## Summary\n\nThe `sanitizeArchivePath` function in `webserver/api/v1/decoder.go` (lines 80-88) is vulnerable to a path traversal bypass due to a missing trailing path separator in the `strings.HasPrefix` check. A crafted tar archive can write files outside the intended destination directory.\n\n## Vulnerable Code\n\nFile: `webserver/api/v1/decoder.go`, lines 80-88\n\n```go\nfunc sanitizeArchivePath(d, t string) (v string, err error) {\n\tv = filepath.Join(d, t)\n\tif strings.HasPrefix(v, filepath.Clean(d)) {\n\t\treturn v, nil\n\t}\n\treturn \"\", &ErrPathTainted{\n\t\tPath: t,\n\t}\n}\n```\n\nThe function is called at line 48 inside `[*Decompressor].Unzip`, which is invoked by `Decode` (line 80) during execution of the webserver CLI (command `download`).\n\n## Root Cause\n\n`strings.HasPrefix(v, filepath.Clean(d))` does not append a trailing `/` to the directory prefix, causing a **directory name prefix collision**. If the destination is `/home/user/extract-output` and a tar entry is named `../extract-outputevil/pwned`, the joined path `/home/user/extract-outputevil/pwned` passes the prefix check — it starts with `/home/user/extract-output` — even though it is entirely outside the intended directory.\n\n## Steps to Reproduce\n\n1. **Deploy Romeo**. A measured app writes its coverage data.\n\n2. **Place the PoC zip on the PVC.** Any pod with write access to the `ReadWriteMany` PVC (or the webserver itself) copies a `poc-path-traversal.tar` into the `coverdir` mount path. The archive contains legitimate coverage files alongside two crafted entries with path-traversal names.\n\n3. **Run the webserver CLI against the running webserver:**\n ```\n webserver download \\\n --server http://localhost:8080 \\\n --directory /home/user/extract-output\n ```\n\n4. **Observe the bypass.** `unzip` processes the zip stream. For the malicious entries:\n ```\n // entry name: ../extract-outputevil/poc-proof.txt\n filepath.Join(\"/home/user/extract-output\", \"../extract-outputevil/poc-proof.txt\")\n => \"/home/user/extract-outputevil/poc-proof.txt\"\n\n strings.HasPrefix(\"/home/user/extract-outputevil/poc-proof.txt\",\n \"/home/user/extract-output\")\n => true // BUG: prefix collision; file lands OUTSIDE target dir\n ```\n Both malicious entries are written outside `/home/user/extract-output/`. The legitimate coverage files land correctly inside it.\n\n## Impact\n\nSuccessful exploitation gives an attacker arbitrary file write on the machine running the webserver CLI. Real-world primitives include:\n\n- Overwriting `~/.bashrc` / `~/.zshrc` / `~/.profile` for RCE on next shell login\n- Appending to `~/.ssh/authorized_keys` for persistent SSH backdoor\n- Dropping a malicious entry into `~/.kube/config` to hijack cluster access\n- Writing crontab entries for persistent scheduled execution\n\nThe attack surface is widened by the default `ReadWriteMany` PVC access mode, which means any pod in the cluster with the PVC mounted can inject the payload — not just the Romeo webserver itself.",
911
"severity": [

advisories/github-reviewed/2026/03/GHSA-wvwj-cvrp-7pv5/GHSA-wvwj-cvrp-7pv5.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-wvwj-cvrp-7pv5",
4-
"modified": "2026-03-16T15:17:15Z",
4+
"modified": "2026-03-16T21:53:55Z",
55
"published": "2026-03-16T15:17:15Z",
66
"aliases": [
77
"CVE-2026-27962"
@@ -43,6 +43,10 @@
4343
"type": "WEB",
4444
"url": "https://github.com/authlib/authlib/security/advisories/GHSA-wvwj-cvrp-7pv5"
4545
},
46+
{
47+
"type": "ADVISORY",
48+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27962"
49+
},
4650
{
4751
"type": "WEB",
4852
"url": "https://github.com/authlib/authlib/commit/a5d4b2d4c9e46bfa11c82f85fdc2bcc0b50ae681"
@@ -63,6 +67,6 @@
6367
"severity": "CRITICAL",
6468
"github_reviewed": true,
6569
"github_reviewed_at": "2026-03-16T15:17:15Z",
66-
"nvd_published_at": null
70+
"nvd_published_at": "2026-03-16T18:16:07Z"
6771
}
6872
}

0 commit comments

Comments
 (0)