Common Weakness Enumeration

CWE-180

Allowed

Incorrect Behavior Order: Validate Before Canonicalize

Abstraction: Variant · Status: Draft

The product validates input before it is canonicalized, which prevents the product from detecting data that becomes invalid after the canonicalization step.

33 vulnerabilities reference this CWE, most recent first.

GHSA-7JMW-8259-Q9JX

Vulnerability from github – Published: 2024-06-11 19:29 – Updated: 2024-06-17 15:28
VLAI
Summary
Traefik has unexpected behavior with IPv4-mapped IPv6 addresses
Details

Impact

There is a vulnerability in Go managing various Is methods (IsPrivate, IsLoopback, etc) for IPv4-mapped IPv6 addresses.

They didn't work as expected returning false for addresses which would return true in their traditional IPv4 forms.

References

Patches

  • https://github.com/traefik/traefik/releases/tag/v2.11.4
  • https://github.com/traefik/traefik/releases/tag/v3.0.2

Workarounds

No workaround.

For more information

If you have any questions or comments about this advisory, please open an issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/traefik/traefik/v3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0-beta3"
            },
            {
              "fixed": "3.0.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/traefik/traefik/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.11.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/traefik/traefik"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.11.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-180"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-06-11T19:29:43Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Impact\n\nThere is a vulnerability in [Go managing various Is methods (IsPrivate, IsLoopback, etc) for IPv4-mapped IPv6 addresses](https://groups.google.com/g/golang-announce/c/XbxouI9gY7k/m/TuoGEhxIEwAJ).\n\nThey didn\u0027t work as expected returning false for addresses which would return true in their traditional IPv4 forms.\n\n### References\n\n- [CVE-2024-24790](https://www.cve.org/CVERecord?id=CVE-2024-24790)\n\n### Patches\n\n- https://github.com/traefik/traefik/releases/tag/v2.11.4\n- https://github.com/traefik/traefik/releases/tag/v3.0.2\n\n### Workarounds\n\nNo workaround.\n\n### For more information\n\nIf you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues).",
  "id": "GHSA-7jmw-8259-q9jx",
  "modified": "2024-06-17T15:28:38Z",
  "published": "2024-06-11T19:29:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/security/advisories/GHSA-7jmw-8259-q9jx"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/traefik/traefik"
    },
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/releases/tag/v2.11.4"
    },
    {
      "type": "WEB",
      "url": "https://github.com/traefik/traefik/releases/tag/v3.0.2"
    },
    {
      "type": "WEB",
      "url": "https://pkg.go.dev/vuln/GO-2024-2917"
    },
    {
      "type": "WEB",
      "url": "https://www.cve.org/CVERecord?id=CVE-2024-24790"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [],
  "summary": "Traefik has unexpected behavior with IPv4-mapped IPv6 addresses"
}

GHSA-8R66-VG6C-X88H

Vulnerability from github – Published: 2025-11-25 18:32 – Updated: 2025-11-25 18:32
VLAI
Details

NVIDIA DGX Spark GB10 contains a vulnerability in SROOT firmware, where an attacker could cause improper processing of input data. A successful exploit of this vulnerability might lead to information disclosure or denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-33194"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-11-25T18:15:51Z",
    "severity": "MODERATE"
  },
  "details": "NVIDIA DGX Spark GB10 contains a vulnerability in SROOT firmware, where an attacker could cause improper processing of input data. A successful exploit of this vulnerability might lead to information disclosure or denial of service.",
  "id": "GHSA-8r66-vg6c-x88h",
  "modified": "2025-11-25T18:32:22Z",
  "published": "2025-11-25T18:32:22Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-33194"
    },
    {
      "type": "WEB",
      "url": "https://nvidia.custhelp.com/app/answers/detail/a_id/5720"
    },
    {
      "type": "WEB",
      "url": "https://www.cve.org/CVERecord?id=CVE-2025-33194"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-92H7-Q9M9-98H8

Vulnerability from github – Published: 2025-04-23 15:30 – Updated: 2025-04-23 15:30
VLAI
Details

A directory traversal vulnerability exists in Ivanti LANDesk Management Gateway through 4.2-1.9. By appending %3F.php to the URI of the /client/index.php endpoint, an attacker can bypass access controls and gain unauthorized access to various endpoints such as /client/index.php%3F.php/gsb/firewall.php within the management web panel, potentially exposing sensitive device information. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-43716"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-23T14:15:29Z",
    "severity": "MODERATE"
  },
  "details": "A directory traversal vulnerability exists in Ivanti LANDesk Management Gateway through 4.2-1.9. By appending %3F.php to the URI of the /client/index.php endpoint, an attacker can bypass access controls and gain unauthorized access to various endpoints such as /client/index.php%3F.php/gsb/firewall.php within the management web panel, potentially exposing sensitive device information. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.",
  "id": "GHSA-92h7-q9m9-98h8",
  "modified": "2025-04-23T15:30:57Z",
  "published": "2025-04-23T15:30:57Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-43716"
    },
    {
      "type": "WEB",
      "url": "https://forums.ivanti.com/s/article/Graphical-overview-of-the-LANDesk-Management-Gateway-Functionality"
    },
    {
      "type": "WEB",
      "url": "https://medium.com/@0xbytehunter/discovery-of-path-traversal-vulnerability-in-landesk-management-gateway-devices-6dba386dd290"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-94VH-GPHV-8PM8

Vulnerability from github – Published: 2025-03-17 21:26 – Updated: 2025-03-19 15:51
VLAI
Summary
zip Incorrectly Canonicalizes Paths during Archive Extraction Leading to Arbitrary File Write
Details

Summary

In the archive extraction routine of affected versions of the zip crate, symbolic links earlier in the archive are allowed to be used for later files in the archive without validation of the final canonicalized path, allowing maliciously crafted archives to overwrite arbitrary files in the file system when extracted.

Details

This is a variant of the zip-slip vulnerability, we can make the extraction logic step outside of the target directory by creating a symlink to the parent directory and then extracting further files through that symlink.

The documentation of the [::zip::read::ZipArchive::extract] method is in my opinion implying this should not happen:

"Paths are sanitized with ZipFile::enclosed_name." ... [::zip::read::FileOptions::enclosed_name] ... is resistant to path-based exploits ... can’t resolve to a path outside the current directory.

Most archive software either decline to extract symlinks that traverse out of the directory or defer creation of symlinks after all files have been created to prevent unexpected behavior when later entries depend on earlier symbolic link entries.

PoC

https://gist.github.com/eternal-flame-AD/bf71ef4f6828e741eb12ce7fd47b7b85

Impact

Users who extract untrusted archive files using the following high-level API method may be affected and critical files on the system may be overwritten with arbitrary file permissions, which can potentially lead to code execution.

  • zip::unstable::stream::ZipStreamReader::extract
  • zip::read::ZipArchive::extract
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "crates.io",
        "name": "zip"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.3.0"
            },
            {
              "fixed": "2.3.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-29787"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180",
      "CWE-22",
      "CWE-61"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-03-17T21:26:32Z",
    "nvd_published_at": "2025-03-17T14:15:22Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\n\nIn the archive extraction routine of affected versions of the `zip` crate, symbolic links earlier in the archive are allowed to be used for later files in the archive without validation of the final canonicalized path, allowing maliciously crafted archives to overwrite arbitrary files in the file system when extracted.\n\n### Details\n\nThis is a variant of the [zip-slip](https://github.com/snyk/zip-slip-vulnerability) vulnerability, we can make the extraction logic step outside of the target directory by creating a symlink to the parent directory and then extracting further files through that symlink.\n\nThe documentation of the [`::zip::read::ZipArchive::extract`] method is in my opinion implying this should not happen:\n\n\u003e \"Paths are sanitized with ZipFile::enclosed_name.\" ...\n\u003e [`::zip::read::FileOptions::enclosed_name`] ... is resistant to path-based exploits ... can\u2019t resolve to a path outside the current directory.\n\n\nMost archive software either decline to extract symlinks that traverse out of the directory or defer creation of symlinks after all files have been created to prevent unexpected behavior when later entries depend on earlier symbolic link entries.\n\n### PoC\n\nhttps://gist.github.com/eternal-flame-AD/bf71ef4f6828e741eb12ce7fd47b7b85\n\n### Impact\n\nUsers who extract untrusted archive files using the following high-level API method may be affected and critical files on the system may be overwritten with arbitrary file permissions, which can potentially lead to code execution.\n\n- zip::unstable::stream::ZipStreamReader::extract\n- zip::read::ZipArchive::extract",
  "id": "GHSA-94vh-gphv-8pm8",
  "modified": "2025-03-19T15:51:04Z",
  "published": "2025-03-17T21:26:32Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/zip-rs/zip2/security/advisories/GHSA-94vh-gphv-8pm8"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29787"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zip-rs/zip2/commit/a2e062f37066c3b12860a32eb1cb44856cfb7afe"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/eternal-flame-AD/bf71ef4f6828e741eb12ce7fd47b7b85"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/zip-rs/zip2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/zip-rs/zip2/releases/tag/v2.3.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:L/VI:H/VA:N/SC:H/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "zip Incorrectly Canonicalizes Paths during Archive Extraction Leading to Arbitrary File Write"
}

GHSA-9RFG-V8G9-9367

Vulnerability from github – Published: 2026-05-26 23:38 – Updated: 2026-06-11 13:30
VLAI
Summary
Fedify has an LD-Signature Bypass via JSON-LD Named-Graph Restructuring
Details

As told on Discord earlier, multiple projects are affected, and we would like to coordinate. For now, we are aiming at a May 6th release date, but this is not set in stone yet.

Summary

An attacker can make use of JSON-LD features to restructure a JSON-LD document that would change how Fedify interprets it without changing its Linked Data Signature, allowing them to alter a third-party signed activity they have received.

Details

The vulnerability essentially boils down to the signature being on the canonical RDF graph representation of the JSON-LD document, and JSON-LD offering many ways to represent the same graph.

One of the issues is that by taking a signed Activity with an embedded object, an attacker can move the top-level Activity to a @graph property and move the activity's object to the top-level. Such a transformation preserves the signature and changes how the payload is interpreted by pretty much all ActivityPub implementations, making them process the object and ignore the formely-top-level activity. This can be used when the graph contains an embedded activity. In Mastodon, that is the case of { "type": "Undo", "object": { "type": "Announce" } }, but other implementations may sign other activities that can be exploited in the same way.

The @reverse keyword can also be used to change the shape of a JSON-LD document without changing the underlying graph, and could be used in a similar way to reverse an Activity and its object.

Another problematic feature is @included, which can be used to “move” properties outside of the normal tree, effectively making them invisible to most ActivityPub implementations, while, again, preserving the signature. This allows removing statuses or actor properties once a signed Create or Update activity is received.

Given that we have seen no use of @graph, @included or @reverse in ActivityPub payloads and that they are very complex to handle correctly (the only JSON-LD API functions that “normalize” @included and @reverse are flattening and framing, which both lose the root node), we have decided to reject them, and recommend you do so as well.

Detection of @graph, @included and @reverse should happen after compacting the incoming activity to your context, as aliases can be used for those keywords.

Additionally, after a quick scan of Fedify's source code, I could not verify that JSON-LD documents with a verified Linked Data Signature were compacted against your local JSON-LD context. Not doing that allows an attacker to rename aliases to non-standard names and use non-mapped aliases to replace existing values, while still leaving the signature intact. This allows an attacker to essentially replace arbitrary portions of any signed JSON-LD document and completely forge any activity while still passing verification. A similar issue was fixed in Mastodon a few years ago: https://github.com/mastodon/mastodon/pull/17426.

Impact

The impact is difficult to assess as this depends on the types of activities that are actually signed and processed in the wild.

The @included keyword allows “removing” arbitrary attributes, thus allowing replaying Create and Update activities while stripping away any attribute, such as content or metadata, which can lead to integrity and availability issues, although confidentiality issues are unlikely.

The @graph and @reverse keywords allow changing the root activity, which in the case of Mastodon allows sending an Announce from a Undo { Announce }, but might have wider consequences depending on what various servers sign.

The lack of compacting can allow rewriting any activity arbitrarily, thus leading to major integrity, availability, and possibly confidentiality issues (e.g. by replacing an actor's inbox).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fedify/fedify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.2.0"
            },
            {
              "fixed": "2.2.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fedify/fedify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.1.0"
            },
            {
              "fixed": "2.1.14"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fedify/fedify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0"
            },
            {
              "fixed": "2.0.18"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fedify/fedify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.10.0"
            },
            {
              "fixed": "1.10.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@fedify/fedify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.9.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42462"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1289",
      "CWE-180",
      "CWE-347",
      "CWE-436"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-26T23:38:37Z",
    "nvd_published_at": "2026-06-10T22:16:57Z",
    "severity": "HIGH"
  },
  "details": "As told on Discord earlier, multiple projects are affected, and we would like to coordinate. For now, we are aiming at a May 6th release date, but this is not set in stone yet.\n\n### Summary\n\nAn attacker can make use of JSON-LD features to restructure a JSON-LD document that would change how Fedify interprets it without changing its Linked Data Signature, allowing them to alter a third-party signed activity they have received.\n\n### Details\n\nThe vulnerability essentially boils down to the signature being on the canonical RDF graph representation of the JSON-LD document, and JSON-LD offering many ways to represent the same graph.\n\nOne of the issues is that by taking a signed `Activity` with an embedded `object`, an attacker can move the top-level `Activity` to a `@graph` property and move the activity\u0027s `object` to the top-level. Such a transformation preserves the signature and changes how the payload is interpreted by pretty much all ActivityPub implementations, making them process the object and ignore the formely-top-level activity. This can be used when the graph contains an embedded activity. In Mastodon, that is the case of `{ \"type\": \"Undo\", \"object\": { \"type\": \"Announce\" } }`, but other implementations may sign other activities that can be exploited in the same way.\n\nThe `@reverse` keyword can also be used to change the shape of a JSON-LD document without changing the underlying graph, and could be used in a similar way to reverse an `Activity` and its `object`.\n\nAnother problematic feature is `@included`, which can be used to \u201cmove\u201d properties outside of the normal tree, effectively making them invisible to most ActivityPub implementations, while, again, preserving the signature. This allows removing statuses or actor properties once a signed `Create` or `Update` activity is received.\n\nGiven that we have seen no use of `@graph`, `@included` or `@reverse` in ActivityPub payloads and that they are very complex to handle correctly (the only JSON-LD API functions that \u201cnormalize\u201d `@included` and `@reverse` are flattening and framing, which both lose the root node), we have decided to reject them, and recommend you do so as well.\n\nDetection of `@graph`, `@included` and `@reverse` should happen after compacting the incoming activity to your context, as aliases can be used for those keywords.\n\nAdditionally, after a quick scan of Fedify\u0027s source code, I could not verify that JSON-LD documents with a verified Linked Data Signature were compacted against your local JSON-LD context. Not doing that allows an attacker to rename aliases to non-standard names and use non-mapped aliases to replace existing values, while still leaving the signature intact. This allows an attacker to essentially replace arbitrary portions of any signed JSON-LD document and completely forge any activity while still passing verification. A similar issue was fixed in Mastodon a few years ago: https://github.com/mastodon/mastodon/pull/17426.\n\n### Impact\n\nThe impact is difficult to assess as this depends on the types of activities that are actually signed and processed in the wild.\n\nThe `@included` keyword allows \u201cremoving\u201d arbitrary attributes, thus allowing replaying `Create` and `Update` activities while stripping away any attribute, such as content or metadata, which can lead to integrity and availability issues, although confidentiality issues are unlikely.\n\nThe `@graph` and `@reverse` keywords allow changing the root activity, which in the case of Mastodon allows sending an `Announce` from a `Undo { Announce }`, but might have wider consequences depending on what various servers sign.\n\nThe lack of compacting can allow rewriting any activity arbitrarily, thus leading to major integrity, availability, and possibly confidentiality issues (e.g. by replacing an actor\u0027s `inbox`).",
  "id": "GHSA-9rfg-v8g9-9367",
  "modified": "2026-06-11T13:30:30Z",
  "published": "2026-05-26T23:38:37Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/fedify-dev/fedify/security/advisories/GHSA-9rfg-v8g9-9367"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42462"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/fedify-dev/fedify"
    },
    {
      "type": "WEB",
      "url": "https://github.com/fedify-dev/fedify/releases/tag/2.2.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Fedify has an LD-Signature Bypass via JSON-LD Named-Graph Restructuring"
}

GHSA-CHQ7-94J8-CJ28

Vulnerability from github – Published: 2026-06-03 21:30 – Updated: 2026-06-03 21:30
VLAI
Summary
Jupyter Enterprise Gateway: ContainerProcessProxy._enforce_prohibited_ids Bypass
Details

Summary

Jupyter Enterprise Gateway has a prohibited UID and GID feature that by default prevents launching kernels with UID or GID 0 (root). This can be bypassed. It is possible to launch kernels with a prohibited UID and/or GID by using a specially crafted KERNEL_UID or KERNEL_GID value.

The feature is described in the documentation:

https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/config-add-env.md?plain=1#L103-L107

https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/config-add-env.md?plain=1#L88-L92

https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/deploy-kubernetes.md?plain=1#L769

Details

The prohibited_uids and prohibited_uids are set based of the OS env var EG_PROHIBITED_UIDS and EG_PROHIBITED_GIDS, and default to the string 0.

https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L29-L30

The checks https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L113 and https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L119 look for the user supplied KERNEL_UID / KERNEL_GID string in the prohibited_uids / prohibited_gids strings. These checks can be bypassed by including whitespace, for example the string 0 (trailing space).

The user supplied string is used in the Kubernetes manifest at https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml.j2#L35 and https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml.j2#L38 where they are parsed as an integer in the Jinja2 template - which will ignore the whitespace.

PoC

How it is meant to work

Trying 0 gets denied, as expected.

xh http://enterprise-gateway.bdawg.svc.cluster.local:8888/api/kernels name=python_kubernetes env:='{"KERNEL_POD_NAME":"bdawg", "KERNEL_UID": "0", "KERNEL_GID": "0"}'
HTTP/1.1 403 Kernel's UID value of '0' has been denied via EG_PROHIBITED_UIDS!
Content-Length: 94
Content-Type: application/json
Date: Mon, 14 Jul 2025 12:57:09 GMT
Server: TornadoServer/6.4.1
X-Content-Type-Options: nosniff
{
    "reason": "Kernel's UID value of '0' has been denied via EG_PROHIBITED_UIDS!",
    "message": ""
}

Exploit bypassing the checks

Using 0 with a trailing space, bypasses the check.

xh http://enterprise-gateway.bdawg.svc.cluster.local:8888/api/kernels name=python_kubernetes env:='{"KERNEL_POD_NAME":"bdawg", "KERNEL_UID": "0 ", "KERNEL_GID": "0 "}'
HTTP/1.1 201 Created
Content-Length: 172
Content-Type: application/json
Date: Mon, 14 Jul 2025 14:15:19 GMT
Location: /api/kernels/17eee032-994f-4dd2-8ade-87169c300a40
Server: TornadoServer/6.4.1
X-Content-Type-Options: nosniff
{
    "id": "17eee032-994f-4dd2-8ade-87169c300a40",
    "name": "python_kubernetes",
    "last_activity": "2025-07-14T14:15:21.468155Z",
    "execution_state": "starting",
    "connections": 0
}

The pod is successfully scheduled.

Inspecting the container we can see it is running as root:

kubectl exec -it pod/bdawg -- bash
(base) root@bdawg3:~# id
uid=0(root) gid=0(root) groups=0(root),100(users)

If we had not supplied the KERNEL_UID / KERNEL_GID the container would have been running as UID:GID 1000:100 (jovyan:users).

Impact

This input validation vulnerability allows running Jupyter kernels as root, which can be dangerous as it allows more attack surface, and may lead to container escapes, compromising the worker node and all workloads running on it. Repeated exploitation can compromise all worker nodes, and thus the entire Kubernetes cluster. It is possible to specify volume mounts, so one vector for a container escape is to use a hostPath R/W volume mount, use this UID/GID bypass to run as root, and then gain code execution in the underlying worker node by creating a crontab entry in the mounted host file system.

Organisations running Jupyter Enterprise Gateway to host Jupyter Kernels on at least Kubernetes clusters (I've tested this), and possibly on any other supported container orchestration systems or systems that utilise the KERNEL_UID and KERNEL_GID variables with the EG_PROHIBITED_UIDS and EG_PROHIBITED_GIDS feature.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "jupyter_enterprise_gateway"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.0.0rc1"
            },
            {
              "fixed": "3.3.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44180"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180",
      "CWE-20"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-03T21:30:10Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "### Summary\n\nJupyter Enterprise Gateway has a prohibited UID and GID feature that by default prevents launching kernels with UID or GID 0 (root).\nThis can be bypassed. It is possible to launch kernels with a prohibited UID and/or GID by using a specially crafted `KERNEL_UID` or `KERNEL_GID` value.\n\nThe feature is described in the documentation: \n\nhttps://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/config-add-env.md?plain=1#L103-L107\n\nhttps://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/config-add-env.md?plain=1#L88-L92\n\nhttps://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/docs/source/operators/deploy-kubernetes.md?plain=1#L769\n\n### Details\n\nThe `prohibited_uids` and `prohibited_uids` are set based of the OS env var `EG_PROHIBITED_UIDS` and `EG_PROHIBITED_GIDS`, and default to the string `0`.\n\nhttps://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L29-L30\n\nThe checks https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L113 and https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/enterprise_gateway/services/processproxies/container.py#L119 look for the user supplied `KERNEL_UID` / `KERNEL_GID` string in the `prohibited_uids` / `prohibited_gids` strings. These checks can be bypassed by including whitespace, for example the string `0 ` (trailing space).\n\nThe user supplied string is used in the Kubernetes manifest at https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml.j2#L35 and https://github.com/jupyter-server/enterprise_gateway/blob/152c20f162f2fab700c04c8830ebf8c1e2e2217a/etc/kernel-launchers/kubernetes/scripts/kernel-pod.yaml.j2#L38 where they are parsed as an integer in the Jinja2 template - which will ignore the whitespace.\n\n### PoC\n\n\n#### How it is meant to work\n\nTrying `0` gets denied, as expected.\n\n```bash\nxh http://enterprise-gateway.bdawg.svc.cluster.local:8888/api/kernels name=python_kubernetes env:=\u0027{\"KERNEL_POD_NAME\":\"bdawg\", \"KERNEL_UID\": \"0\", \"KERNEL_GID\": \"0\"}\u0027\n```\n\n```\nHTTP/1.1 403 Kernel\u0027s UID value of \u00270\u0027 has been denied via EG_PROHIBITED_UIDS!\nContent-Length: 94\nContent-Type: application/json\nDate: Mon, 14 Jul 2025 12:57:09 GMT\nServer: TornadoServer/6.4.1\nX-Content-Type-Options: nosniff\n```\n\n```json\n{\n    \"reason\": \"Kernel\u0027s UID value of \u00270\u0027 has been denied via EG_PROHIBITED_UIDS!\",\n    \"message\": \"\"\n}\n```\n\n#### Exploit bypassing the checks\n\nUsing `0 ` with a trailing space, bypasses the check.\n\n```bash\nxh http://enterprise-gateway.bdawg.svc.cluster.local:8888/api/kernels name=python_kubernetes env:=\u0027{\"KERNEL_POD_NAME\":\"bdawg\", \"KERNEL_UID\": \"0 \", \"KERNEL_GID\": \"0 \"}\u0027\n```\n\n```\nHTTP/1.1 201 Created\nContent-Length: 172\nContent-Type: application/json\nDate: Mon, 14 Jul 2025 14:15:19 GMT\nLocation: /api/kernels/17eee032-994f-4dd2-8ade-87169c300a40\nServer: TornadoServer/6.4.1\nX-Content-Type-Options: nosniff\n```\n\n```\n{\n    \"id\": \"17eee032-994f-4dd2-8ade-87169c300a40\",\n    \"name\": \"python_kubernetes\",\n    \"last_activity\": \"2025-07-14T14:15:21.468155Z\",\n    \"execution_state\": \"starting\",\n    \"connections\": 0\n}\n```\n\nThe pod is successfully scheduled.\n\nInspecting the container we can see it is running as `root`:\n\n```bash\nkubectl exec -it pod/bdawg -- bash\n```\n\n```\n(base) root@bdawg3:~# id\nuid=0(root) gid=0(root) groups=0(root),100(users)\n```\n\nIf we had not supplied the `KERNEL_UID` / `KERNEL_GID` the container would have been running as UID:GID `1000:100` (`jovyan:users`).\n\n### Impact\n\nThis input validation vulnerability allows running Jupyter kernels as root, which can be dangerous as it allows more attack surface, and may lead to container escapes, compromising the worker node and all workloads running on it. Repeated exploitation can compromise all worker nodes, and thus the entire Kubernetes cluster. It is possible to specify volume mounts, so one vector for a container escape is to use a `hostPath` R/W volume mount, use this UID/GID bypass to run as root, and then gain code execution in the underlying worker node by creating a crontab entry in the mounted host file system.\n\nOrganisations running Jupyter Enterprise Gateway to host Jupyter Kernels on at least Kubernetes clusters (I\u0027ve tested this), and possibly on any other supported container orchestration systems or systems that utilise the `KERNEL_UID` and `KERNEL_GID` variables with the `EG_PROHIBITED_UIDS` and `EG_PROHIBITED_GIDS` feature.",
  "id": "GHSA-chq7-94j8-cj28",
  "modified": "2026-06-03T21:30:10Z",
  "published": "2026-06-03T21:30:10Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/jupyter-server/enterprise_gateway/security/advisories/GHSA-chq7-94j8-cj28"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jupyter-server/enterprise_gateway"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jupyter-server/enterprise_gateway/releases/tag/v3.3.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Jupyter Enterprise Gateway: ContainerProcessProxy._enforce_prohibited_ids Bypass"
}

GHSA-F3MV-W3V5-88QP

Vulnerability from github – Published: 2022-07-21 00:00 – Updated: 2022-08-05 00:00
VLAI
Details

A vulnerability in multiple Atlassian products allows a remote, unauthenticated attacker to bypass Servlet Filters used by first and third party apps. The impact depends on which filters are used by each app, and how the filters are used. This vulnerability can result in authentication bypass and cross-site scripting. Atlassian has released updates that fix the root cause of this vulnerability, but has not exhaustively enumerated all potential consequences of this vulnerability. Atlassian Bamboo versions are affected before 8.0.9, from 8.1.0 before 8.1.8, and from 8.2.0 before 8.2.4. Atlassian Bitbucket versions are affected before 7.6.16, from 7.7.0 before 7.17.8, from 7.18.0 before 7.19.5, from 7.20.0 before 7.20.2, from 7.21.0 before 7.21.2, and versions 8.0.0 and 8.1.0. Atlassian Confluence versions are affected before 7.4.17, from 7.5.0 before 7.13.7, from 7.14.0 before 7.14.3, from 7.15.0 before 7.15.2, from 7.16.0 before 7.16.4, from 7.17.0 before 7.17.4, and version 7.21.0. Atlassian Crowd versions are affected before 4.3.8, from 4.4.0 before 4.4.2, and version 5.0.0. Atlassian Fisheye and Crucible versions before 4.8.10 are affected. Atlassian Jira versions are affected before 8.13.22, from 8.14.0 before 8.20.10, and from 8.21.0 before 8.22.4. Atlassian Jira Service Management versions are affected before 4.13.22, from 4.14.0 before 4.20.10, and from 4.21.0 before 4.22.4.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-26136"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180",
      "CWE-287"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-07-20T18:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "A vulnerability in multiple Atlassian products allows a remote, unauthenticated attacker to bypass Servlet Filters used by first and third party apps. The impact depends on which filters are used by each app, and how the filters are used. This vulnerability can result in authentication bypass and cross-site scripting. Atlassian has released updates that fix the root cause of this vulnerability, but has not exhaustively enumerated all potential consequences of this vulnerability. Atlassian Bamboo versions are affected before 8.0.9, from 8.1.0 before 8.1.8, and from 8.2.0 before 8.2.4. Atlassian Bitbucket versions are affected before 7.6.16, from 7.7.0 before 7.17.8, from 7.18.0 before 7.19.5, from 7.20.0 before 7.20.2, from 7.21.0 before 7.21.2, and versions 8.0.0 and 8.1.0. Atlassian Confluence versions are affected before 7.4.17, from 7.5.0 before 7.13.7, from 7.14.0 before 7.14.3, from 7.15.0 before 7.15.2, from 7.16.0 before 7.16.4, from 7.17.0 before 7.17.4, and version 7.21.0. Atlassian Crowd versions are affected before 4.3.8, from 4.4.0 before 4.4.2, and version 5.0.0. Atlassian Fisheye and Crucible versions before 4.8.10 are affected. Atlassian Jira versions are affected before 8.13.22, from 8.14.0 before 8.20.10, and from 8.21.0 before 8.22.4. Atlassian Jira Service Management versions are affected before 4.13.22, from 4.14.0 before 4.20.10, and from 4.21.0 before 4.22.4.",
  "id": "GHSA-f3mv-w3v5-88qp",
  "modified": "2022-08-05T00:00:28Z",
  "published": "2022-07-21T00:00:27Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-26136"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/BAM-21795"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/BSERV-13370"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CONFSERVER-79476"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CRUC-8541"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CWD-5815"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/FE-7410"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/JRASERVER-73897"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/JSDSERVER-11863"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-FPJ5-PCGC-34G7

Vulnerability from github – Published: 2022-07-21 00:00 – Updated: 2024-10-03 18:30
VLAI
Details

A vulnerability in multiple Atlassian products allows a remote, unauthenticated attacker to cause additional Servlet Filters to be invoked when the application processes requests or responses. Atlassian has confirmed and fixed the only known security issue associated with this vulnerability: Cross-origin resource sharing (CORS) bypass. Sending a specially crafted HTTP request can invoke the Servlet Filter used to respond to CORS requests, resulting in a CORS bypass. An attacker that can trick a user into requesting a malicious URL can access the vulnerable application with the victim’s permissions. Atlassian Bamboo versions are affected before 8.0.9, from 8.1.0 before 8.1.8, and from 8.2.0 before 8.2.4. Atlassian Bitbucket versions are affected before 7.6.16, from 7.7.0 before 7.17.8, from 7.18.0 before 7.19.5, from 7.20.0 before 7.20.2, from 7.21.0 before 7.21.2, and versions 8.0.0 and 8.1.0. Atlassian Confluence versions are affected before 7.4.17, from 7.5.0 before 7.13.7, from 7.14.0 before 7.14.3, from 7.15.0 before 7.15.2, from 7.16.0 before 7.16.4, from 7.17.0 before 7.17.4, and version 7.21.0. Atlassian Crowd versions are affected before 4.3.8, from 4.4.0 before 4.4.2, and version 5.0.0. Atlassian Fisheye and Crucible versions before 4.8.10 are affected. Atlassian Jira versions are affected before 8.13.22, from 8.14.0 before 8.20.10, and from 8.21.0 before 8.22.4. Atlassian Jira Service Management versions are affected before 4.13.22, from 4.14.0 before 4.20.10, and from 4.21.0 before 4.22.4.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-26137"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180",
      "CWE-346"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-07-20T18:15:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in multiple Atlassian products allows a remote, unauthenticated attacker to cause additional Servlet Filters to be invoked when the application processes requests or responses. Atlassian has confirmed and fixed the only known security issue associated with this vulnerability: Cross-origin resource sharing (CORS) bypass. Sending a specially crafted HTTP request can invoke the Servlet Filter used to respond to CORS requests, resulting in a CORS bypass. An attacker that can trick a user into requesting a malicious URL can access the vulnerable application with the victim\u2019s permissions. Atlassian Bamboo versions are affected before 8.0.9, from 8.1.0 before 8.1.8, and from 8.2.0 before 8.2.4. Atlassian Bitbucket versions are affected before 7.6.16, from 7.7.0 before 7.17.8, from 7.18.0 before 7.19.5, from 7.20.0 before 7.20.2, from 7.21.0 before 7.21.2, and versions 8.0.0 and 8.1.0. Atlassian Confluence versions are affected before 7.4.17, from 7.5.0 before 7.13.7, from 7.14.0 before 7.14.3, from 7.15.0 before 7.15.2, from 7.16.0 before 7.16.4, from 7.17.0 before 7.17.4, and version 7.21.0. Atlassian Crowd versions are affected before 4.3.8, from 4.4.0 before 4.4.2, and version 5.0.0. Atlassian Fisheye and Crucible versions before 4.8.10 are affected. Atlassian Jira versions are affected before 8.13.22, from 8.14.0 before 8.20.10, and from 8.21.0 before 8.22.4. Atlassian Jira Service Management versions are affected before 4.13.22, from 4.14.0 before 4.20.10, and from 4.21.0 before 4.22.4.",
  "id": "GHSA-fpj5-pcgc-34g7",
  "modified": "2024-10-03T18:30:34Z",
  "published": "2022-07-21T00:00:27Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-26137"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/BAM-21795"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/BSERV-13370"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CONFSERVER-79476"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CRUC-8541"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/CWD-5815"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/FE-7410"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/JRASERVER-73897"
    },
    {
      "type": "WEB",
      "url": "https://jira.atlassian.com/browse/JSDSERVER-11863"
    }
  ],
  "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"
    }
  ]
}

GHSA-G966-83W7-6W38

Vulnerability from github – Published: 2026-02-12 15:29 – Updated: 2026-02-12 22:07
VLAI
Summary
FrankenPHP's unicode case-folding length expansion causes incorrect split_path index (SCRIPT_NAME/PATH_INFO confusion) in FrankenPHP
Details

Summary

FrankenPHP’s CGI path splitting logic improperly handles Unicode characters during case conversion. The logic computes the split index (for finding .php) on a lowercased copy of the request path but applies that byte index to the original path.

Because strings.ToLower() in Go can increase the byte length of certain UTF-8 characters (e.g., Ⱥ expands when lowercased), the computed index may not align with the correct position in the original string. This results in an incorrect SCRIPT_NAME and SCRIPT_FILENAME, potentially causing FrankenPHP to execute a file other than the one intended by the URI.

Details

The vulnerability resides in the splitPos() function and its usage within splitCgiPath(). The logic attempts to find the script extension (e.g., .php) in a case-insensitive manner by lowercasing the path:

lowerPath := strings.ToLower(path)
idx := strings.Index(lowerPath, strings.ToLower(split))
return idx + len(split)

The issue is that the returned idx represents a byte offset within lowerPath. However, splitCgiPath() uses this index to slice the original path:

fc.docURI = path[:splitPos]
fc.pathInfo = path[splitPos:]
fc.scriptName = strings.TrimSuffix(path, fc.pathInfo)
fc.scriptFilename = sanitizedPathJoin(fc.documentRoot, fc.scriptName)

This logic relies on the assumption that len(strings.ToLower(path)) == len(path). This assumption is false for certain Unicode characters. For example, the character Ⱥ (U+023A) requires 2 bytes in UTF-8 (0xC8 0xBA), but its lowercase equivalent (U+2C65) requires 3 bytes (0xE2 0xB1 0xA5).

If the path contains such characters before the .php extension, the index calculated on lowerPath will be larger than the corresponding visual point in the original path. When applied to the original path, the split occurs at the wrong byte offset. This can cause the server to treat a larger portion of the path as the script name, effectively allowing an attacker to manipulate SCRIPT_FILENAME.

PoC

The following Go program demonstrates the discrepancy between the byte index in the lowercased string versus the original string.

  1. Save the following as poc.go:
package main

import (
    "fmt"
    "strings"
)

func splitPos(path string, split string) int {
    lowerPath := strings.ToLower(path)
    idx := strings.Index(lowerPath, strings.ToLower(split))
    if idx < 0 {
        return -1
    }
    return idx + len(split)
}

func main() {
    // U+023A: Ⱥ (UTF-8: C8 BA). Lowercase is ⱥ (UTF-8: E2 B1 A5), longer in bytes.
    // We construct a path where the byte expansion shifts the index.
    path := "/ȺȺȺȺshell.php.txt.php"
    split := ".php"

    pos := splitPos(path, split)

    fmt.Printf("orig bytes=%d\n", len(path))
    fmt.Printf("lower bytes=%d\n", len(strings.ToLower(path)))
    fmt.Printf("splitPos=%d\n", pos)

    // Current Unsafe Behavior:
    fmt.Printf("orig[:pos] (Calculated Script)=%q\n", path[:pos])
    fmt.Printf("orig[pos:] (Calculated PathInfo)=%q\n", path[pos:])

    // Expected Safe Behavior:
    want := strings.Index(path, split) + len(split)
    fmt.Printf("expected splitPos=%d\n", want)
    fmt.Printf("expected orig[:]=%q\n", path[:want])
}
  1. Run the PoC:
go run poc.go
  1. Output:
orig bytes=26
lower bytes=30
splitPos=22
orig[:pos]="/ȺȺȺȺshell.php.txt"
orig[pos:]=".php"
expected splitPos=18
expected orig[:]="/ȺȺȺȺshell.php"

In this example, FrankenPHP would identify /ȺȺȺȺshell.php.txt as the PHP script to execute, ignoring the fact that the actual file extension in the file system might be .txt.

Impact*

This is a Security Boundary Bypass and Path Confusion vulnerability.

In setups where users can upload files (e.g., avatars, text files) that are stored within the document root or a reachable path, an attacker can upload a file containing malicious PHP code with a safe extension (e.g., payload.txt). By crafting a request with specific Unicode characters, the attacker can force FrankenPHP to calculate the SCRIPT_FILENAME as ending in payload.txt, while the request appears to contain .php to the internal router logic.

This results in the execution of non-PHP files as PHP scripts, leading to Remote Code Execution (RCE).

Patched Versions

  • This issue is fixed in FrankenPHP version 1.11.2.

Workarounds

  • Ensure that user-uploaded files are stored outside of the public document root.
  • Implement strict WAF rules to reject requests containing specific multi-byte Unicode characters in the URL path if an upgrade is not immediately possible.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/dunglas/frankenphp"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.11.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-24895"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180",
      "CWE-20"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-12T15:29:36Z",
    "nvd_published_at": "2026-02-12T20:16:10Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nFrankenPHP\u2019s CGI path splitting logic improperly handles Unicode characters during case conversion. The logic computes the split index (for finding `.php`) on a lowercased copy of the request path but applies that byte index to the original path.\n\nBecause `strings.ToLower()` in Go can increase the byte length of certain UTF-8 characters (e.g., `\u023a` expands when lowercased), the computed index may not align with the correct position in the original string. This results in an incorrect `SCRIPT_NAME` and `SCRIPT_FILENAME`, potentially causing FrankenPHP to execute a file other than the one intended by the URI.\n\n### **Details**\n\nThe vulnerability resides in the `splitPos()` function and its usage within `splitCgiPath()`. The logic attempts to find the script extension (e.g., `.php`) in a case-insensitive manner by lowercasing the path:\n\n```go\nlowerPath := strings.ToLower(path)\nidx := strings.Index(lowerPath, strings.ToLower(split))\nreturn idx + len(split)\n```\n\nThe issue is that the returned `idx` represents a byte offset within `lowerPath`. However, `splitCgiPath()` uses this index to slice the **original** `path`:\n\n```go\nfc.docURI = path[:splitPos]\nfc.pathInfo = path[splitPos:]\nfc.scriptName = strings.TrimSuffix(path, fc.pathInfo)\nfc.scriptFilename = sanitizedPathJoin(fc.documentRoot, fc.scriptName)\n```\n\nThis logic relies on the assumption that `len(strings.ToLower(path)) == len(path)`. This assumption is false for certain Unicode characters. For example, the character `\u023a` (U+023A) requires 2 bytes in UTF-8 (`0xC8 0xBA`), but its lowercase equivalent `\u2c65` (U+2C65) requires 3 bytes (`0xE2 0xB1 0xA5`).\n\nIf the path contains such characters before the `.php` extension, the index calculated on `lowerPath` will be larger than the corresponding visual point in the original `path`. When applied to the original path, the split occurs at the wrong byte offset. This can cause the server to treat a larger portion of the path as the script name, effectively allowing an attacker to manipulate `SCRIPT_FILENAME`.\n\n### **PoC**\n\nThe following Go program demonstrates the discrepancy between the byte index in the lowercased string versus the original string.\n\n1. Save the following as `poc.go`:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"strings\"\n)\n\nfunc splitPos(path string, split string) int {\n    lowerPath := strings.ToLower(path)\n    idx := strings.Index(lowerPath, strings.ToLower(split))\n    if idx \u003c 0 {\n        return -1\n    }\n    return idx + len(split)\n}\n\nfunc main() {\n    // U+023A: \u023a (UTF-8: C8 BA). Lowercase is \u2c65 (UTF-8: E2 B1 A5), longer in bytes.\n    // We construct a path where the byte expansion shifts the index.\n    path := \"/\u023a\u023a\u023a\u023ashell.php.txt.php\"\n    split := \".php\"\n\n    pos := splitPos(path, split)\n\n    fmt.Printf(\"orig bytes=%d\\n\", len(path))\n    fmt.Printf(\"lower bytes=%d\\n\", len(strings.ToLower(path)))\n    fmt.Printf(\"splitPos=%d\\n\", pos)\n\n    // Current Unsafe Behavior:\n    fmt.Printf(\"orig[:pos] (Calculated Script)=%q\\n\", path[:pos])\n    fmt.Printf(\"orig[pos:] (Calculated PathInfo)=%q\\n\", path[pos:])\n\n    // Expected Safe Behavior:\n    want := strings.Index(path, split) + len(split)\n    fmt.Printf(\"expected splitPos=%d\\n\", want)\n    fmt.Printf(\"expected orig[:]=%q\\n\", path[:want])\n}\n```\n\n2. Run the PoC:\n\n```console\ngo run poc.go\n```\n\n3. **Output:**\n\n```text\norig bytes=26\nlower bytes=30\nsplitPos=22\norig[:pos]=\"/\u023a\u023a\u023a\u023ashell.php.txt\"\norig[pos:]=\".php\"\nexpected splitPos=18\nexpected orig[:]=\"/\u023a\u023a\u023a\u023ashell.php\"\n```\n\nIn this example, FrankenPHP would identify `/\u023a\u023a\u023a\u023ashell.php.txt` as the PHP script to execute, ignoring the fact that the actual file extension in the file system might be `.txt`.\n\n### Impact*\n\nThis is a **Security Boundary Bypass** and **Path Confusion** vulnerability.\n\nIn setups where users can upload files (e.g., avatars, text files) that are stored within the document root or a reachable path, an attacker can upload a file containing malicious PHP code with a safe extension (e.g., `payload.txt`). By crafting a request with specific Unicode characters, the attacker can force FrankenPHP to calculate the `SCRIPT_FILENAME` as ending in `payload.txt`, while the request appears to contain `.php` to the internal router logic.\n\nThis results in the execution of non-PHP files as PHP scripts, leading to **Remote Code Execution (RCE)**.\n\n### **Patched Versions**\n\n* This issue is fixed in FrankenPHP version **1.11.2**.\n\n### **Workarounds**\n\n* Ensure that user-uploaded files are stored outside of the public document root.\n* Implement strict WAF rules to reject requests containing specific multi-byte Unicode characters in the URL path if an upgrade is not immediately possible.",
  "id": "GHSA-g966-83w7-6w38",
  "modified": "2026-02-12T22:07:57Z",
  "published": "2026-02-12T15:29:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/php/frankenphp/security/advisories/GHSA-g966-83w7-6w38"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-24895"
    },
    {
      "type": "WEB",
      "url": "https://github.com/php/frankenphp/commit/04fdc0c1e8fde94e2c1ad86217e962c88d27c53e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/php/frankenphp"
    },
    {
      "type": "WEB",
      "url": "https://github.com/php/frankenphp/releases/tag/v1.11.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/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"
    }
  ],
  "summary": "FrankenPHP\u0027s unicode case-folding length expansion causes incorrect split_path index (SCRIPT_NAME/PATH_INFO confusion) in FrankenPHP"
}

GHSA-M9GQ-CMCJ-P62X

Vulnerability from github – Published: 2026-03-27 21:31 – Updated: 2026-03-27 21:31
VLAI
Details

Varnish Cache before 8.0.1 and Varnish Enterprise before 6.0.16r12, in certain unchecked req.url scenarios, mishandle URLs with a path of / for HTTP/1.1, potentially leading to cache poisoning or authentication bypass.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-34475"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-180"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-03-27T20:16:36Z",
    "severity": "MODERATE"
  },
  "details": "Varnish Cache before 8.0.1 and Varnish Enterprise before 6.0.16r12, in certain unchecked req.url scenarios, mishandle URLs with a path of / for HTTP/1.1, potentially leading to cache poisoning or authentication bypass.",
  "id": "GHSA-m9gq-cmcj-p62x",
  "modified": "2026-03-27T21:31:37Z",
  "published": "2026-03-27T21:31:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34475"
    },
    {
      "type": "WEB",
      "url": "https://vinyl-cache.org/security/VSV00018.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation MIT-20
Implementation

Strategy: Input Validation

Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180). Make sure that the application does not decode the same input twice (CWE-174). Such errors could be used to bypass allowlist validation schemes by introducing dangerous inputs after they have been checked.

CAPEC-267: Leverage Alternate Encoding

An adversary leverages the possibility to encode potentially harmful input or content used by applications such that the applications are ineffective at validating this encoding standard.

CAPEC-3: Using Leading 'Ghost' Character Sequences to Bypass Input Filters

Some APIs will strip certain leading characters from a string of parameters. An adversary can intentionally introduce leading "ghost" characters (extra characters that don't affect the validity of the request at the API layer) that enable the input to pass the filters and therefore process the adversary's input. This occurs when the targeted API will accept input data in several syntactic forms and interpret it in the equivalent semantic way, while the filter does not take into account the full spectrum of the syntactic forms acceptable to the targeted API.

CAPEC-71: Using Unicode Encoding to Bypass Validation Logic

An attacker may provide a Unicode string to a system component that is not Unicode aware and use that to circumvent the filter or cause the classifying mechanism to fail to properly understanding the request. That may allow the attacker to slip malicious data past the content filter and/or possibly cause the application to route the request incorrectly.

CAPEC-78: Using Escaped Slashes in Alternate Encoding

This attack targets the use of the backslash in alternate encoding. An adversary can provide a backslash as a leading character and causes a parser to believe that the next character is special. This is called an escape. By using that trick, the adversary tries to exploit alternate ways to encode the same character which leads to filter problems and opens avenues to attack.

CAPEC-79: Using Slashes in Alternate Encoding

This attack targets the encoding of the Slash characters. An adversary would try to exploit common filtering problems related to the use of the slashes characters to gain access to resources on the target host. Directory-driven systems, such as file systems and databases, typically use the slash character to indicate traversal between directories or other container components. For murky historical reasons, PCs (and, as a result, Microsoft OSs) choose to use a backslash, whereas the UNIX world typically makes use of the forward slash. The schizophrenic result is that many MS-based systems are required to understand both forms of the slash. This gives the adversary many opportunities to discover and abuse a number of common filtering problems. The goal of this pattern is to discover server software that only applies filters to one version, but not the other.

CAPEC-80: Using UTF-8 Encoding to Bypass Validation Logic

This attack is a specific variation on leveraging alternate encodings to bypass validation logic. This attack leverages the possibility to encode potentially harmful input in UTF-8 and submit it to applications not expecting or effective at validating this encoding standard making input filtering difficult. UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. Legal UTF-8 characters are one to four bytes long. However, early version of the UTF-8 specification got some entries wrong (in some cases it permitted overlong characters). UTF-8 encoders are supposed to use the "shortest possible" encoding, but naive decoders may accept encodings that are longer than necessary. According to the RFC 3629, a particularly subtle form of this attack can be carried out against a parser which performs security-critical validity checks against the UTF-8 encoded form of its input, but interprets certain illegal octet sequences as characters.