Search
Find a vulnerability
Search criteria
ⓘ
Use this form to refine search results.
Full-text search supports keyword queries with ranking and filtering.
You can combine vendor, product, and sources to narrow results.
Enable “Apply ordering” to sort by date instead of relevance.
304 vulnerabilities
CVE-2026-86688 (GCVE-0-2026-86688)
Vulnerability from cvelistv5 – Published: 2026-09-17 21:58 – Updated: 2026-09-18 14:31
VLAI
EPSS
VEX
Title
Session id is not renewed on authentication in ash_authentication, allowing session fixation
Summary
Session Fixation vulnerability in team-alembic ash_authentication allows an attacker who can plant a session identifier in a victim's browser to hold an authenticated session once that victim signs in.
AshAuthentication.Plug.Helpers.store_in_session/2 writes the authenticated subject into the existing session with Plug.Conn.put_session/3 and never calls Plug.Conn.configure_session(renew: true), so the identifier the visitor arrived with carries into their authenticated session. Every authentication event reaches this one function: the default success/4 injected by AshAuthentication.Phoenix.Controller.__using__/1, the AuthController emitted by mix ash_authentication_phoenix.install, and remember-me auto-login. AshAuthentication.Phoenix.Plug.store_in_session/2 is a defdelegate to it. Logout does not close the window either, because clear_session/2 ends with Plug.Conn.clear_session/1, which clears session contents but leaves the identifier intact, so a planted identifier survives a logout-then-login cycle.
This issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-18 14:24 UTC
CWE
- CWE-384 - Session Fixation
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
0.2.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
a939dde9b917c072cdf10c4b0913a9886a4b0231 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-86688",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-18T14:24:09.606894Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-18T14:31:41.961Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "0.2.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "872db454405ecad4fcdabd9ff3d8755d1d6a69ae",
"status": "unaffected"
},
{
"at": "3e1d452cbf1564e87f5f97be882b66fe25af7cfa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "a939dde9b917c072cdf10c4b0913a9886a4b0231",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eExploitation for account takeover requires a server-side session store (ETS, Mnesia, Redis or a database), where the cookie carries a stable session identifier, and a position from which the attacker can plant that cookie in the victim\u0027s browser: cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser.\u003c/p\u003e\n\u003cp\u003ePhoenix defaults to the signed cookie store, and neither package\u0027s installer changes it. Under that store the authenticated session lives in the re-signed cookie delivered only to the victim, so a planted pre-authentication copy does not become an authenticated session. Attacker-planted session contents, such as a \u003ccode\u003ereturn_to\u003c/code\u003e value, still survive into the authenticated session there.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Exploitation for account takeover requires a server-side session store (ETS, Mnesia, Redis or a database), where the cookie carries a stable session identifier, and a position from which the attacker can plant that cookie in the victim\u0027s browser: cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser.\n\nPhoenix defaults to the signed cookie store, and neither package\u0027s installer changes it. Under that store the authenticated session lives in the re-signed cookie delivered only to the victim, so a planted pre-authentication copy does not become an authenticated session. Attacker-planted session contents, such as a `return_to` value, still survive into the authenticated session there."
}
],
"value": "Exploitation for account takeover requires a server-side session store (ETS, Mnesia, Redis or a database), where the cookie carries a stable session identifier, and a position from which the attacker can plant that cookie in the victim\u0027s browser: cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser.\n\nPhoenix defaults to the signed cookie store, and neither package\u0027s installer changes it. Under that store the authenticated session lives in the re-signed cookie delivered only to the victim, so a planted pre-authentication copy does not become an authenticated session. Attacker-planted session contents, such as a return_to value, still survive into the authenticated session there."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "0.2.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-17T05:24:11.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eSession Fixation vulnerability in team-alembic ash_authentication allows an attacker who can plant a session identifier in a victim\u0027s browser to hold an authenticated session once that victim signs in.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Plug.Helpers.store_in_session/2\u003c/code\u003e writes the authenticated subject into the existing session with \u003ccode\u003ePlug.Conn.put_session/3\u003c/code\u003e and never calls \u003ccode\u003ePlug.Conn.configure_session(renew: true)\u003c/code\u003e, so the identifier the visitor arrived with carries into their authenticated session. Every authentication event reaches this one function: the default \u003ccode\u003esuccess/4\u003c/code\u003e injected by \u003ccode\u003eAshAuthentication.Phoenix.Controller.__using__/1\u003c/code\u003e, the \u003ccode\u003eAuthController\u003c/code\u003e emitted by \u003ccode\u003emix ash_authentication_phoenix.install\u003c/code\u003e, and remember-me auto-login. \u003ccode\u003eAshAuthentication.Phoenix.Plug.store_in_session/2\u003c/code\u003e is a \u003ccode\u003edefdelegate\u003c/code\u003e to it. Logout does not close the window either, because \u003ccode\u003eclear_session/2\u003c/code\u003e ends with \u003ccode\u003ePlug.Conn.clear_session/1\u003c/code\u003e, which clears session contents but leaves the identifier intact, so a planted identifier survives a logout-then-login cycle.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Session Fixation vulnerability in team-alembic ash_authentication allows an attacker who can plant a session identifier in a victim\u0027s browser to hold an authenticated session once that victim signs in.\n\n`AshAuthentication.Plug.Helpers.store_in_session/2` writes the authenticated subject into the existing session with `Plug.Conn.put_session/3` and never calls `Plug.Conn.configure_session(renew: true)`, so the identifier the visitor arrived with carries into their authenticated session. Every authentication event reaches this one function: the default `success/4` injected by `AshAuthentication.Phoenix.Controller.__using__/1`, the `AuthController` emitted by `mix ash_authentication_phoenix.install`, and remember-me auto-login. `AshAuthentication.Phoenix.Plug.store_in_session/2` is a `defdelegate` to it. Logout does not close the window either, because `clear_session/2` ends with `Plug.Conn.clear_session/1`, which clears session contents but leaves the identifier intact, so a planted identifier survives a logout-then-login cycle.\n\nThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Session Fixation vulnerability in team-alembic ash_authentication allows an attacker who can plant a session identifier in a victim\u0027s browser to hold an authenticated session once that victim signs in.\n\nAshAuthentication.Plug.Helpers.store_in_session/2 writes the authenticated subject into the existing session with Plug.Conn.put_session/3 and never calls Plug.Conn.configure_session(renew: true), so the identifier the visitor arrived with carries into their authenticated session. Every authentication event reaches this one function: the default success/4 injected by AshAuthentication.Phoenix.Controller.__using__/1, the AuthController emitted by mix ash_authentication_phoenix.install, and remember-me auto-login. AshAuthentication.Phoenix.Plug.store_in_session/2 is a defdelegate to it. Logout does not close the window either, because clear_session/2 ends with Plug.Conn.clear_session/1, which clears session contents but leaves the identifier intact, so a planted identifier survives a logout-then-login cycle.\n\nThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-61",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker holding a session identifier they planted before the victim signed in gains that victim\u0027s authenticated session, and with it full account takeover, in deployments using a server-side session store.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker holding a session identifier they planted before the victim signed in gains that victim\u0027s authenticated session, and with it full account takeover, in deployments using a server-side session store."
}
],
"value": "An attacker holding a session identifier they planted before the victim signed in gains that victim\u0027s authenticated session, and with it full account takeover, in deployments using a server-side session store."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 7.4,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "ACTIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-384",
"description": "CWE-384 Session Fixation",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T21:58:00.853Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-v577-944g-7h3x"
},
{
"name": "EEF CNA record for CVE-2026-86688",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-86688.html"
},
{
"name": "OSV record EEF-CVE-2026-86688",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-86688"
},
{
"name": "Introducing commit a939dde in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/a939dde9b917c072cdf10c4b0913a9886a4b0231"
},
{
"name": "Fix commit 872db45 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/872db454405ecad4fcdabd9ff3d8755d1d6a69ae"
},
{
"name": "Fix commit 3e1d452 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/3e1d452cbf1564e87f5f97be882b66fe25af7cfa"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Session id is not renewed on authentication in ash_authentication, allowing session fixation",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eCall \u003ccode\u003ePlug.Conn.configure_session(conn, renew: true)\u003c/code\u003e in your own \u003ccode\u003esuccess/4\u003c/code\u003e before \u003ccode\u003estore_in_session/2\u003c/code\u003e. This is a one-line change in application code and closes the controller sign-in path, though not remember-me auto-login, which does not pass through application code.\u003c/p\u003e\n\u003cp\u003eAdd \u003ccode\u003ePlug.Conn.configure_session(conn, drop: true)\u003c/code\u003e at sign-out so a planted identifier does not survive a logout-then-login cycle.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Call `Plug.Conn.configure_session(conn, renew: true)` in your own `success/4` before `store_in_session/2`. This is a one-line change in application code and closes the controller sign-in path, though not remember-me auto-login, which does not pass through application code.\n\nAdd `Plug.Conn.configure_session(conn, drop: true)` at sign-out so a planted identifier does not survive a logout-then-login cycle."
}
],
"value": "Call Plug.Conn.configure_session(conn, renew: true) in your own success/4 before store_in_session/2. This is a one-line change in application code and closes the controller sign-in path, though not remember-me auto-login, which does not pass through application code.\n\nAdd Plug.Conn.configure_session(conn, drop: true) at sign-out so a planted identifier does not survive a logout-then-login cycle."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-86688",
"datePublished": "2026-09-17T21:58:00.853Z",
"dateReserved": "2026-09-17T00:30:01.485Z",
"dateUpdated": "2026-09-18T14:31:41.961Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-76949 (GCVE-0-2026-76949)
Vulnerability from cvelistv5 – Published: 2026-09-17 21:57 – Updated: 2026-09-18 14:31
VLAI
EPSS
VEX
Title
Remember-me sign-in guard reads a session key that is never written in ash_authentication, allowing session replacement
Summary
Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who can plant a remember-me cookie in a victim's browser to replace that victim's authenticated session with one for the attacker's own account.
AshAuthentication.Plug.Helpers.sign_in_using_remember_me/3 skips re-authenticating an already-signed-in visitor by checking the session for "<subject_name>_token", but store_in_session/2 writes that key only when require_token_presence_for_authentication? is enabled and otherwise writes the bare subject name. At the default setting the guard therefore reads a key that is never written, its already-signed-in branch is unreachable, and the remember-me sign-in runs on every request through the per-request browser pipeline plug. A planted remember-me cookie is consequently honoured even for a visitor holding a live authenticated session, so whatever the victim enters afterwards lands in data the attacker controls. The read path in authenticate_resource_from_session/4 selects the key correctly, so the guard and the reader disagree about which key holds the session.
This issue affects ash_authentication: from 4.10.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-18 14:24 UTC
CWE
- CWE-290 - Authentication Bypass by Spoofing
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.10.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
3d3de314692558d06ec13945f857f00514e95a8c , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-76949",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-18T14:24:28.652087Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-18T14:31:41.806Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Plug.Helpers\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/plug/helpers.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:sign_in_using_remember_me/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:store_in_session/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.10.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Plug.Helpers\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/plug/helpers.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:sign_in_using_remember_me/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:store_in_session/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "b9568a53b438247238b1c5a4f49c8d84650f4bba",
"status": "unaffected"
},
{
"at": "9a34136b844abe179da1075067cf2835c64dcc12",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "3d3de314692558d06ec13945f857f00514e95a8c",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe application must enable the \u003ccode\u003eremember_me\u003c/code\u003e strategy and run its per-request plug in the browser pipeline, with \u003ccode\u003erequire_token_presence_for_authentication?\u003c/code\u003e at its default of \u003ccode\u003efalse\u003c/code\u003e. Enabling that setting makes the guard read the key the session actually holds, which closes the issue.\u003c/p\u003e\n\u003cp\u003eThe attacker also needs a position from which to set a cookie in the victim\u0027s browser, such as cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The application must enable the `remember_me` strategy and run its per-request plug in the browser pipeline, with `require_token_presence_for_authentication?` at its default of `false`. Enabling that setting makes the guard read the key the session actually holds, which closes the issue.\n\nThe attacker also needs a position from which to set a cookie in the victim\u0027s browser, such as cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser."
}
],
"value": "The application must enable the remember_me strategy and run its per-request plug in the browser pipeline, with require_token_presence_for_authentication? at its default of false. Enabling that setting makes the guard read the key the session actually holds, which closes the issue.\n\nThe attacker also needs a position from which to set a cookie in the victim\u0027s browser, such as cookie tossing from a sibling subdomain, an HTTP host without HSTS, or a shared or kiosk browser."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.10.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-17T14:23:56.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAuthentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who can plant a remember-me cookie in a victim\u0027s browser to replace that victim\u0027s authenticated session with one for the attacker\u0027s own account.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Plug.Helpers.sign_in_using_remember_me/3\u003c/code\u003e skips re-authenticating an already-signed-in visitor by checking the session for \u003ccode\u003e\"\u0026lt;subject_name\u0026gt;_token\"\u003c/code\u003e, but \u003ccode\u003estore_in_session/2\u003c/code\u003e writes that key only when \u003ccode\u003erequire_token_presence_for_authentication?\u003c/code\u003e is enabled and otherwise writes the bare subject name. At the default setting the guard therefore reads a key that is never written, its already-signed-in branch is unreachable, and the remember-me sign-in runs on every request through the per-request browser pipeline plug. A planted remember-me cookie is consequently honoured even for a visitor holding a live authenticated session, so whatever the victim enters afterwards lands in data the attacker controls. The read path in \u003ccode\u003eauthenticate_resource_from_session/4\u003c/code\u003e selects the key correctly, so the guard and the reader disagree about which key holds the session.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.10.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who can plant a remember-me cookie in a victim\u0027s browser to replace that victim\u0027s authenticated session with one for the attacker\u0027s own account.\n\n`AshAuthentication.Plug.Helpers.sign_in_using_remember_me/3` skips re-authenticating an already-signed-in visitor by checking the session for `\"\u003csubject_name\u003e_token\"`, but `store_in_session/2` writes that key only when `require_token_presence_for_authentication?` is enabled and otherwise writes the bare subject name. At the default setting the guard therefore reads a key that is never written, its already-signed-in branch is unreachable, and the remember-me sign-in runs on every request through the per-request browser pipeline plug. A planted remember-me cookie is consequently honoured even for a visitor holding a live authenticated session, so whatever the victim enters afterwards lands in data the attacker controls. The read path in `authenticate_resource_from_session/4` selects the key correctly, so the guard and the reader disagree about which key holds the session.\n\nThis issue affects ash_authentication: from 4.10.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who can plant a remember-me cookie in a victim\u0027s browser to replace that victim\u0027s authenticated session with one for the attacker\u0027s own account.\n\nAshAuthentication.Plug.Helpers.sign_in_using_remember_me/3 skips re-authenticating an already-signed-in visitor by checking the session for \"\u003csubject_name\u003e_token\", but store_in_session/2 writes that key only when require_token_presence_for_authentication? is enabled and otherwise writes the bare subject name. At the default setting the guard therefore reads a key that is never written, its already-signed-in branch is unreachable, and the remember-me sign-in runs on every request through the per-request browser pipeline plug. A planted remember-me cookie is consequently honoured even for a visitor holding a live authenticated session, so whatever the victim enters afterwards lands in data the attacker controls. The read path in authenticate_resource_from_session/4 selects the key correctly, so the guard and the reader disagree about which key holds the session.\n\nThis issue affects ash_authentication: from 4.10.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-21",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker who can set a remember-me cookie in a victim\u0027s browser silently replaces the victim\u0027s authenticated session with one for the attacker\u0027s own account, so data the victim subsequently enters is written to records the attacker controls. The victim is given no indication their identity changed.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker who can set a remember-me cookie in a victim\u0027s browser silently replaces the victim\u0027s authenticated session with one for the attacker\u0027s own account, so data the victim subsequently enters is written to records the attacker controls. The victim is given no indication their identity changed."
}
],
"value": "An attacker who can set a remember-me cookie in a victim\u0027s browser silently replaces the victim\u0027s authenticated session with one for the attacker\u0027s own account, so data the victim subsequently enters is written to records the attacker controls. The victim is given no indication their identity changed."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-290",
"description": "CWE-290 Authentication Bypass by Spoofing",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T21:57:50.146Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-hh34-374j-pfr5"
},
{
"name": "EEF CNA record for CVE-2026-76949",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-76949.html"
},
{
"name": "OSV record EEF-CVE-2026-76949",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-76949"
},
{
"name": "Introducing commit 3d3de31 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/3d3de314692558d06ec13945f857f00514e95a8c"
},
{
"name": "Fix commit b9568a5 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/b9568a53b438247238b1c5a4f49c8d84650f4bba"
},
{
"name": "Fix commit 9a34136 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/9a34136b844abe179da1075067cf2835c64dcc12"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Remember-me sign-in guard reads a session key that is never written in ash_authentication, allowing session replacement",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eSet \u003ccode\u003erequire_token_presence_for_authentication? true\u003c/code\u003e on the authenticated resource\u0027s token configuration. \u003ccode\u003estore_in_session/2\u003c/code\u003e then writes the key the guard reads, so the already-signed-in branch fires and the remember-me sign-in no longer runs against a live session. Note this changes session storage semantics for the whole application and requires a token resource.\u003c/p\u003e\n\u003cp\u003eOtherwise remove the remember-me plug from the browser pipeline, which disables remember-me auto-login entirely.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Set `require_token_presence_for_authentication? true` on the authenticated resource\u0027s token configuration. `store_in_session/2` then writes the key the guard reads, so the already-signed-in branch fires and the remember-me sign-in no longer runs against a live session. Note this changes session storage semantics for the whole application and requires a token resource.\n\nOtherwise remove the remember-me plug from the browser pipeline, which disables remember-me auto-login entirely."
}
],
"value": "Set require_token_presence_for_authentication? true on the authenticated resource\u0027s token configuration. store_in_session/2 then writes the key the guard reads, so the already-signed-in branch fires and the remember-me sign-in no longer runs against a live session. Note this changes session storage semantics for the whole application and requires a token resource.\n\nOtherwise remove the remember-me plug from the browser pipeline, which disables remember-me auto-login entirely."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-76949",
"datePublished": "2026-09-17T21:57:50.146Z",
"dateReserved": "2026-09-17T05:30:01.744Z",
"dateUpdated": "2026-09-18T14:31:41.806Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-91039 (GCVE-0-2026-91039)
Vulnerability from cvelistv5 – Published: 2026-09-17 15:19 – Updated: 2026-09-17 19:40
VLAI
EPSS
VEX
Title
dynamic_oidc identities are not namespaced by connection in ash_authentication, allowing cross-connection account takeover
Summary
Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who operates one identity-provider connection of a dynamic_oidc strategy to be signed in as a local user established through a different connection.
The strategy is meant to keep each connection in its own identity namespace by writing every UserIdentity row's strategy field as "<name>/<connection_id>", but that namespacing never takes effect. __connection_id__ is populated only on the ephemeral runtime struct built per request in dynamic_oidc/plug.ex, and DynamicOidc.IdentityChange.change/3 re-fetches the strategy from the compile-time DSL through Info.strategy_for_action, yielding the persisted struct whose __connection_id__ is its defstruct default of nil. OAuth2.identity_strategy_name/1 therefore falls back to the bare strategy name for both the identity write and the reads in oauth2/user_resolver.ex and oauth2/sign_in_preparation.ex. Since the identity resource's unique key is (uid, strategy), one row exists per sub across every connection, and the identity-match branch runs before any email check. Neither strategy handles iss, so nothing else distinguishes the issuers: OpenID Connect Core section 5.7 makes sub unique only within an issuer, so two connections numbering subjects independently share one subject space.
This issue affects ash_authentication: from 5.0.0-rc.10 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 19:40 UTC
CWE
- CWE-290 - Authentication Bypass by Spoofing
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/team-alembic/ash_authenticatio… | relatedvendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-91039.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-91039 | related |
| https://github.com/team-alembic/ash_authenticatio… | related |
| https://github.com/team-alembic/ash_authenticatio… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
5.0.0-rc.10 , < 5.0.0-rc.14
(semver)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
64530644f9b37ebb76ca14aeb83a77597a0034b7 , < 73ad16e452670bbf843550a13361bd41e72ad964
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-91039",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T19:40:12.687953Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T19:40:32.068Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.10",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "73ad16e452670bbf843550a13361bd41e72ad964",
"status": "affected",
"version": "64530644f9b37ebb76ca14aeb83a77597a0034b7",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eOnly deployments running a \u003ccode\u003edynamic_oidc\u003c/code\u003e strategy with more than one identity-provider connection are exposed, since a single connection has no second namespace to collide with.\u003c/p\u003e\n\u003cp\u003eTwo partial mitigations exist and neither is sufficient. A \u003ccode\u003econfirmation\u003c/code\u003e add-on incidentally blocks the takeover only while the victim is unconfirmed, leaving confirmed victims and confirmation-free applications exposed. Ash multitenancy isolates only a one-connection-per-tenant topology, so non-multitenant deployments and tenants holding several connections get no isolation; connection namespacing is orthogonal to tenancy.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Only deployments running a `dynamic_oidc` strategy with more than one identity-provider connection are exposed, since a single connection has no second namespace to collide with.\n\nTwo partial mitigations exist and neither is sufficient. A `confirmation` add-on incidentally blocks the takeover only while the victim is unconfirmed, leaving confirmed victims and confirmation-free applications exposed. Ash multitenancy isolates only a one-connection-per-tenant topology, so non-multitenant deployments and tenants holding several connections get no isolation; connection namespacing is orthogonal to tenancy."
}
],
"value": "Only deployments running a dynamic_oidc strategy with more than one identity-provider connection are exposed, since a single connection has no second namespace to collide with.\n\nTwo partial mitigations exist and neither is sufficient. A confirmation add-on incidentally blocks the takeover only while the victim is unconfirmed, leaving confirmed victims and confirmation-free applications exposed. Ash multitenancy isolates only a one-connection-per-tenant topology, so non-multitenant deployments and tenants holding several connections get no isolation; connection namespacing is orthogonal to tenancy."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.10",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Jace"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "reporter",
"value": "manus-pi"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-17T05:25:04.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAuthentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who operates one identity-provider connection of a \u003ccode\u003edynamic_oidc\u003c/code\u003e strategy to be signed in as a local user established through a different connection.\u003c/p\u003e\n\u003cp\u003eThe strategy is meant to keep each connection in its own identity namespace by writing every \u003ccode\u003eUserIdentity\u003c/code\u003e row\u0027s \u003ccode\u003estrategy\u003c/code\u003e field as \u003ccode\u003e\"\u0026lt;name\u0026gt;/\u0026lt;connection_id\u0026gt;\"\u003c/code\u003e, but that namespacing never takes effect. \u003ccode\u003e__connection_id__\u003c/code\u003e is populated only on the ephemeral runtime struct built per request in \u003ccode\u003edynamic_oidc/plug.ex\u003c/code\u003e, and \u003ccode\u003eDynamicOidc.IdentityChange.change/3\u003c/code\u003e re-fetches the strategy from the compile-time DSL through \u003ccode\u003eInfo.strategy_for_action\u003c/code\u003e, yielding the persisted struct whose \u003ccode\u003e__connection_id__\u003c/code\u003e is its \u003ccode\u003edefstruct\u003c/code\u003e default of \u003ccode\u003enil\u003c/code\u003e. \u003ccode\u003eOAuth2.identity_strategy_name/1\u003c/code\u003e therefore falls back to the bare strategy name for both the identity write and the reads in \u003ccode\u003eoauth2/user_resolver.ex\u003c/code\u003e and \u003ccode\u003eoauth2/sign_in_preparation.ex\u003c/code\u003e. Since the identity resource\u0027s unique key is \u003ccode\u003e(uid, strategy)\u003c/code\u003e, one row exists per \u003ccode\u003esub\u003c/code\u003e across every connection, and the identity-match branch runs before any email check. Neither strategy handles \u003ccode\u003eiss\u003c/code\u003e, so nothing else distinguishes the issuers: OpenID Connect Core section 5.7 makes \u003ccode\u003esub\u003c/code\u003e unique only within an issuer, so two connections numbering subjects independently share one subject space.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 5.0.0-rc.10 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who operates one identity-provider connection of a `dynamic_oidc` strategy to be signed in as a local user established through a different connection.\n\nThe strategy is meant to keep each connection in its own identity namespace by writing every `UserIdentity` row\u0027s `strategy` field as `\"\u003cname\u003e/\u003cconnection_id\u003e\"`, but that namespacing never takes effect. `__connection_id__` is populated only on the ephemeral runtime struct built per request in `dynamic_oidc/plug.ex`, and `DynamicOidc.IdentityChange.change/3` re-fetches the strategy from the compile-time DSL through `Info.strategy_for_action`, yielding the persisted struct whose `__connection_id__` is its `defstruct` default of `nil`. `OAuth2.identity_strategy_name/1` therefore falls back to the bare strategy name for both the identity write and the reads in `oauth2/user_resolver.ex` and `oauth2/sign_in_preparation.ex`. Since the identity resource\u0027s unique key is `(uid, strategy)`, one row exists per `sub` across every connection, and the identity-match branch runs before any email check. Neither strategy handles `iss`, so nothing else distinguishes the issuers: OpenID Connect Core section 5.7 makes `sub` unique only within an issuer, so two connections numbering subjects independently share one subject space.\n\nThis issue affects ash_authentication: from 5.0.0-rc.10 before 5.0.0-rc.14."
}
],
"value": "Authentication Bypass by Spoofing vulnerability in team-alembic ash_authentication allows an attacker who operates one identity-provider connection of a dynamic_oidc strategy to be signed in as a local user established through a different connection.\n\nThe strategy is meant to keep each connection in its own identity namespace by writing every UserIdentity row\u0027s strategy field as \"\u003cname\u003e/\u003cconnection_id\u003e\", but that namespacing never takes effect. __connection_id__ is populated only on the ephemeral runtime struct built per request in dynamic_oidc/plug.ex, and DynamicOidc.IdentityChange.change/3 re-fetches the strategy from the compile-time DSL through Info.strategy_for_action, yielding the persisted struct whose __connection_id__ is its defstruct default of nil. OAuth2.identity_strategy_name/1 therefore falls back to the bare strategy name for both the identity write and the reads in oauth2/user_resolver.ex and oauth2/sign_in_preparation.ex. Since the identity resource\u0027s unique key is (uid, strategy), one row exists per sub across every connection, and the identity-match branch runs before any email check. Neither strategy handles iss, so nothing else distinguishes the issuers: OpenID Connect Core section 5.7 makes sub unique only within an issuer, so two connections numbering subjects independently share one subject space.\n\nThis issue affects ash_authentication: from 5.0.0-rc.10 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-21",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker who can obtain or choose their \u003ccode\u003esub\u003c/code\u003e on any connection served by a \u003ccode\u003edynamic_oidc\u003c/code\u003e strategy is authenticated as the local user established through a different connection, with no interaction from the victim and no pre-existing account on the application. Token, nonce and audience validation all pass legitimately, because they only prove the assertion came from the attacker\u0027s own identity provider.\u003c/p\u003e\n\u003cp\u003eThe same collision also occurs with no attacker at all: two honest providers numbering subjects sequentially produce overlapping \u003ccode\u003esub\u003c/code\u003e values and silently merge distinct users, so this may already have happened in affected deployments.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker who can obtain or choose their `sub` on any connection served by a `dynamic_oidc` strategy is authenticated as the local user established through a different connection, with no interaction from the victim and no pre-existing account on the application. Token, nonce and audience validation all pass legitimately, because they only prove the assertion came from the attacker\u0027s own identity provider.\n\nThe same collision also occurs with no attacker at all: two honest providers numbering subjects sequentially produce overlapping `sub` values and silently merge distinct users, so this may already have happened in affected deployments."
}
],
"value": "An attacker who can obtain or choose their sub on any connection served by a dynamic_oidc strategy is authenticated as the local user established through a different connection, with no interaction from the victim and no pre-existing account on the application. Token, nonce and audience validation all pass legitimately, because they only prove the assertion came from the attacker\u0027s own identity provider.\n\nThe same collision also occurs with no attacker at all: two honest providers numbering subjects sequentially produce overlapping sub values and silently merge distinct users, so this may already have happened in affected deployments."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-290",
"description": "CWE-290 Authentication Bypass by Spoofing",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T15:19:15.994Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-73j9-m294-fvv9"
},
{
"name": "EEF CNA record for CVE-2026-91039",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-91039.html"
},
{
"name": "OSV record EEF-CVE-2026-91039",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-91039"
},
{
"name": "Introducing commit 6453064 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/64530644f9b37ebb76ca14aeb83a77597a0034b7"
},
{
"name": "Fix commit 73ad16e in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/73ad16e452670bbf843550a13361bd41e72ad964"
}
],
"solutions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUpgrading is not sufficient on its own, for two reasons.\u003c/p\u003e\n\u003cp\u003eNamespacing changes the value the identity lookup keys on, so \u003ccode\u003eUserIdentity\u003c/code\u003e rows written before the fix, all holding the bare strategy name, no longer match. Each row\u0027s \u003ccode\u003estrategy\u003c/code\u003e must be relinked in place to \u003ccode\u003e\"\u0026lt;name\u0026gt;/\u0026lt;connection_id\u0026gt;\"\u003c/code\u003e. Deleting the rows does not work: the block is the account match that follows, refused under the default \u003ccode\u003eon_untrusted_email_match :reject\u003c/code\u003e whether the row exists or not, and deleting also discards the stored refresh token. Where a deployment has one connection the mapping is unambiguous and the update is mechanical, but it must run in the same deployment as the upgrade and before users sign in, or a newly written namespaced row can collide with a surviving bare row on the \u003ccode\u003e(uid, strategy)\u003c/code\u003e index.\u003c/p\u003e\n\u003cp\u003eThe fix also cannot separate accounts already merged, and the merge is not detectable from the database, because a collision never produced two rows to compare: the second user\u0027s identity was never created and the surviving row looks legitimate. Deployments running more than one connection must audit out of band, by exporting each connection\u0027s set of \u003ccode\u003esub\u003c/code\u003e values from its identity provider and intersecting them. Any \u003ccode\u003esub\u003c/code\u003e present in more than one set identifies an account that may have been merged.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Upgrading is not sufficient on its own, for two reasons.\n\nNamespacing changes the value the identity lookup keys on, so `UserIdentity` rows written before the fix, all holding the bare strategy name, no longer match. Each row\u0027s `strategy` must be relinked in place to `\"\u003cname\u003e/\u003cconnection_id\u003e\"`. Deleting the rows does not work: the block is the account match that follows, refused under the default `on_untrusted_email_match :reject` whether the row exists or not, and deleting also discards the stored refresh token. Where a deployment has one connection the mapping is unambiguous and the update is mechanical, but it must run in the same deployment as the upgrade and before users sign in, or a newly written namespaced row can collide with a surviving bare row on the `(uid, strategy)` index.\n\nThe fix also cannot separate accounts already merged, and the merge is not detectable from the database, because a collision never produced two rows to compare: the second user\u0027s identity was never created and the surviving row looks legitimate. Deployments running more than one connection must audit out of band, by exporting each connection\u0027s set of `sub` values from its identity provider and intersecting them. Any `sub` present in more than one set identifies an account that may have been merged."
}
],
"value": "Upgrading is not sufficient on its own, for two reasons.\n\nNamespacing changes the value the identity lookup keys on, so UserIdentity rows written before the fix, all holding the bare strategy name, no longer match. Each row\u0027s strategy must be relinked in place to \"\u003cname\u003e/\u003cconnection_id\u003e\". Deleting the rows does not work: the block is the account match that follows, refused under the default on_untrusted_email_match :reject whether the row exists or not, and deleting also discards the stored refresh token. Where a deployment has one connection the mapping is unambiguous and the update is mechanical, but it must run in the same deployment as the upgrade and before users sign in, or a newly written namespaced row can collide with a surviving bare row on the (uid, strategy) index.\n\nThe fix also cannot separate accounts already merged, and the merge is not detectable from the database, because a collision never produced two rows to compare: the second user\u0027s identity was never created and the surviving row looks legitimate. Deployments running more than one connection must audit out of band, by exporting each connection\u0027s set of sub values from its identity provider and intersecting them. Any sub present in more than one set identifies an account that may have been merged."
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "dynamic_oidc identities are not namespaced by connection in ash_authentication, allowing cross-connection account takeover"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-91039",
"datePublished": "2026-09-17T15:19:15.994Z",
"dateReserved": "2026-09-15T15:30:01.883Z",
"dateUpdated": "2026-09-17T19:40:32.068Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-88952 (GCVE-0-2026-88952)
Vulnerability from cvelistv5 – Published: 2026-09-17 14:15 – Updated: 2026-09-17 19:32
VLAI
EPSS
VEX
Title
OAuth2 sign-in attached to an existing account without an email comparison in AshAuthentication
Summary
Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker to be signed in as another user by linking an OAuth2 identity to an account that is not theirs.
AshAuthentication.Strategy.OAuth2.UserResolver.resolve/3 matches an existing account using the register action's upsert_identity keys, then gates linking the incoming provider identity to it on email_trusted?/2, which reads only the provider's email_verified boolean and never compares the provider's email value with the matched account's email. That gate assumes the account was matched by its email field, so under any other upsert_identity it is vacuous and an attacker presenting their own verified email is attached to, and issued a session for, an account matched on some other attribute. The same unguarded gate applies in OAuth2.SignInPreparation on the registration_enabled? false path, where the account is matched by the sign-in action's read filter instead. The upsert also rewrites the matched account's email to the attacker's address, so later account recovery reaches the attacker rather than the owner.
This issue affects ash_authentication: from 4.14.0 before 4.15.0 and from 5.0.0-rc.10 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 19:32 UTC
CWE
- CWE-287 - Improper Authentication
Assigner
References
7 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.14.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.10 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
64530644f9b37ebb76ca14aeb83a77597a0034b7 , < *
(git)
Affected: 42edcd8ebb13fafbb168f12591d7518ce0611fec , < * (git) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-88952",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T19:32:22.090404Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T19:32:55.621Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027",
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.SignInPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.IdentityChange\u0027",
"\u0027Elixir.AshAuthentication.Strategy.DynamicOidc.IdentityChange\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/oauth2/user_resolver.ex",
"lib/ash_authentication/strategies/oauth2/sign_in_preparation.ex",
"lib/ash_authentication/strategies/oauth2/identity_change.ex",
"lib/ash_authentication/strategies/dynamic_oidc/identity_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027:resolve/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027:email_trusted?/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.SignInPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.IdentityChange\u0027:change/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.DynamicOidc.IdentityChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.14.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.10",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027",
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.SignInPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.IdentityChange\u0027",
"\u0027Elixir.AshAuthentication.Strategy.DynamicOidc.IdentityChange\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/oauth2/user_resolver.ex",
"lib/ash_authentication/strategies/oauth2/sign_in_preparation.ex",
"lib/ash_authentication/strategies/oauth2/identity_change.ex",
"lib/ash_authentication/strategies/dynamic_oidc/identity_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027:resolve/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.UserResolver\u0027:email_trusted?/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.SignInPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.IdentityChange\u0027:change/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.DynamicOidc.IdentityChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "738bf9f32f2aa0d1bb92ce9ca5c2476cb5710459",
"status": "unaffected"
},
{
"at": "2bd630eef8b7c8ae1e90e8fd43ba12fbc7e256ba",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "64530644f9b37ebb76ca14aeb83a77597a0034b7",
"versionType": "git"
},
{
"changes": [
{
"at": "738bf9f32f2aa0d1bb92ce9ca5c2476cb5710459",
"status": "unaffected"
},
{
"at": "2bd630eef8b7c8ae1e90e8fd43ba12fbc7e256ba",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "42edcd8ebb13fafbb168f12591d7518ce0611fec",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe strategy must have \u003ccode\u003etrust_email_verified?\u003c/code\u003e enabled, and the account must be matched on something other than the email: a register action whose \u003ccode\u003eupsert_identity\u003c/code\u003e keys are not the email attribute, or, with \u003ccode\u003eregistration_enabled? false\u003c/code\u003e, a sign-in action whose read filter is not the email.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003etrust_email_verified?\u003c/code\u003e defaults to \u003ccode\u003efalse\u003c/code\u003e on the base \u003ccode\u003eoauth2\u003c/code\u003e strategy, but the \u003ccode\u003eapple\u003c/code\u003e, \u003ccode\u003eauth0\u003c/code\u003e, \u003ccode\u003egithub\u003c/code\u003e, \u003ccode\u003egoogle\u003c/code\u003e and \u003ccode\u003eslack\u003c/code\u003e strategies each set it to \u003ccode\u003etrue\u003c/code\u003e in their own DSL.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The strategy must have `trust_email_verified?` enabled, and the account must be matched on something other than the email: a register action whose `upsert_identity` keys are not the email attribute, or, with `registration_enabled? false`, a sign-in action whose read filter is not the email.\n\n`trust_email_verified?` defaults to `false` on the base `oauth2` strategy, but the `apple`, `auth0`, `github`, `google` and `slack` strategies each set it to `true` in their own DSL."
}
],
"value": "The strategy must have trust_email_verified? enabled, and the account must be matched on something other than the email: a register action whose upsert_identity keys are not the email attribute, or, with registration_enabled? false, a sign-in action whose read filter is not the email.\n\ntrust_email_verified? defaults to false on the base oauth2 strategy, but the apple, auth0, github, google and slack strategies each set it to true in their own DSL."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.14.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.10",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "James Harton"
},
{
"lang": "en",
"type": "reporter",
"value": "James Harton"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-17T00:20:23.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Authentication vulnerability in team-alembic AshAuthentication allows an attacker to be signed in as another user by linking an OAuth2 identity to an account that is not theirs.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Strategy.OAuth2.UserResolver.resolve/3\u003c/code\u003e matches an existing account using the register action\u0027s \u003ccode\u003eupsert_identity\u003c/code\u003e keys, then gates linking the incoming provider identity to it on \u003ccode\u003eemail_trusted?/2\u003c/code\u003e, which reads only the provider\u0027s \u003ccode\u003eemail_verified\u003c/code\u003e boolean and never compares the provider\u0027s email value with the matched account\u0027s email. That gate assumes the account was matched by its email field, so under any other \u003ccode\u003eupsert_identity\u003c/code\u003e it is vacuous and an attacker presenting their own verified email is attached to, and issued a session for, an account matched on some other attribute. The same unguarded gate applies in \u003ccode\u003eOAuth2.SignInPreparation\u003c/code\u003e on the \u003ccode\u003eregistration_enabled? false\u003c/code\u003e path, where the account is matched by the sign-in action\u0027s read filter instead. The upsert also rewrites the matched account\u0027s email to the attacker\u0027s address, so later account recovery reaches the attacker rather than the owner.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.14.0 before 4.15.0 and from 5.0.0-rc.10 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker to be signed in as another user by linking an OAuth2 identity to an account that is not theirs.\n\n`AshAuthentication.Strategy.OAuth2.UserResolver.resolve/3` matches an existing account using the register action\u0027s `upsert_identity` keys, then gates linking the incoming provider identity to it on `email_trusted?/2`, which reads only the provider\u0027s `email_verified` boolean and never compares the provider\u0027s email value with the matched account\u0027s email. That gate assumes the account was matched by its email field, so under any other `upsert_identity` it is vacuous and an attacker presenting their own verified email is attached to, and issued a session for, an account matched on some other attribute. The same unguarded gate applies in `OAuth2.SignInPreparation` on the `registration_enabled? false` path, where the account is matched by the sign-in action\u0027s read filter instead. The upsert also rewrites the matched account\u0027s email to the attacker\u0027s address, so later account recovery reaches the attacker rather than the owner.\n\nThis issue affects ash_authentication: from 4.14.0 before 4.15.0 and from 5.0.0-rc.10 before 5.0.0-rc.14."
}
],
"value": "Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker to be signed in as another user by linking an OAuth2 identity to an account that is not theirs.\n\nAshAuthentication.Strategy.OAuth2.UserResolver.resolve/3 matches an existing account using the register action\u0027s upsert_identity keys, then gates linking the incoming provider identity to it on email_trusted?/2, which reads only the provider\u0027s email_verified boolean and never compares the provider\u0027s email value with the matched account\u0027s email. That gate assumes the account was matched by its email field, so under any other upsert_identity it is vacuous and an attacker presenting their own verified email is attached to, and issued a session for, an account matched on some other attribute. The same unguarded gate applies in OAuth2.SignInPreparation on the registration_enabled? false path, where the account is matched by the sign-in action\u0027s read filter instead. The upsert also rewrites the matched account\u0027s email to the attacker\u0027s address, so later account recovery reaches the attacker rather than the owner.\n\nThis issue affects ash_authentication: from 4.14.0 before 4.15.0 and from 5.0.0-rc.10 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-115",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker who controls a provider account with a verified email of their own is signed in as a different local user, holding a session bearing that user\u0027s subject, with no interaction from the victim and no need to pre-register. Because the link also rewrites the matched account\u0027s email to the attacker\u0027s address, account recovery for the victim is redirected to the attacker and the compromise survives the provider identity being unlinked.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker who controls a provider account with a verified email of their own is signed in as a different local user, holding a session bearing that user\u0027s subject, with no interaction from the victim and no need to pre-register. Because the link also rewrites the matched account\u0027s email to the attacker\u0027s address, account recovery for the victim is redirected to the attacker and the compromise survives the provider identity being unlinked."
}
],
"value": "An attacker who controls a provider account with a verified email of their own is signed in as a different local user, holding a session bearing that user\u0027s subject, with no interaction from the victim and no need to pre-register. Because the link also rewrites the matched account\u0027s email to the attacker\u0027s address, account recovery for the victim is redirected to the attacker and the compromise survives the provider identity being unlinked."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-287",
"description": "CWE-287 Improper Authentication",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T14:15:19.506Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-wc6x-276q-jrf9"
},
{
"name": "EEF CNA record for CVE-2026-88952",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-88952.html"
},
{
"name": "OSV record EEF-CVE-2026-88952",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-88952"
},
{
"name": "Introducing commit 6453064 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/64530644f9b37ebb76ca14aeb83a77597a0034b7"
},
{
"name": "Introducing commit 42edcd8 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/42edcd8ebb13fafbb168f12591d7518ce0611fec"
},
{
"name": "Fix commit 738bf9f in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/738bf9f32f2aa0d1bb92ce9ca5c2476cb5710459"
},
{
"name": "Fix commit 2bd630e in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/2bd630eef8b7c8ae1e90e8fd43ba12fbc7e256ba"
}
],
"solutions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUpgrading prevents new links but does not unpick existing ones. An account already linked through this path stays linked, and a victim\u0027s email may already have been rewritten to the attacker\u0027s address.\u003c/p\u003e\n\u003cp\u003eOperators whose register action or sign-in action matched on anything other than the email should review their \u003ccode\u003eUserIdentity\u003c/code\u003e rows for links whose provider email does not match the linked account\u0027s email, and check affected accounts for a rewritten email address.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Upgrading prevents new links but does not unpick existing ones. An account already linked through this path stays linked, and a victim\u0027s email may already have been rewritten to the attacker\u0027s address.\n\nOperators whose register action or sign-in action matched on anything other than the email should review their `UserIdentity` rows for links whose provider email does not match the linked account\u0027s email, and check affected accounts for a rewritten email address."
}
],
"value": "Upgrading prevents new links but does not unpick existing ones. An account already linked through this path stays linked, and a victim\u0027s email may already have been rewritten to the attacker\u0027s address.\n\nOperators whose register action or sign-in action matched on anything other than the email should review their UserIdentity rows for links whose provider email does not match the linked account\u0027s email, and check affected accounts for a rewritten email address."
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "OAuth2 sign-in attached to an existing account without an email comparison in AshAuthentication",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eSet \u003ccode\u003etrust_email_verified? false\u003c/code\u003e on the affected strategy, which refuses the sign-in rather than linking it and closes both the register and the sign-in path.\u003c/p\u003e\n\u003cp\u003eAlternatively, key the register action\u0027s \u003ccode\u003eupsert_identity\u003c/code\u003e, or the sign-in action\u0027s read filter, on the email attribute, which restores the premise the gate assumes.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Set `trust_email_verified? false` on the affected strategy, which refuses the sign-in rather than linking it and closes both the register and the sign-in path.\n\nAlternatively, key the register action\u0027s `upsert_identity`, or the sign-in action\u0027s read filter, on the email attribute, which restores the premise the gate assumes."
}
],
"value": "Set trust_email_verified? false on the affected strategy, which refuses the sign-in rather than linking it and closes both the register and the sign-in path.\n\nAlternatively, key the register action\u0027s upsert_identity, or the sign-in action\u0027s read filter, on the email attribute, which restores the premise the gate assumes."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-88952",
"datePublished": "2026-09-17T14:15:19.506Z",
"dateReserved": "2026-09-16T10:30:02.169Z",
"dateUpdated": "2026-09-17T19:32:55.621Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-85500 (GCVE-0-2026-85500)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:12
VLAI
EPSS
VEX
Title
`require_confirmed_with` is not enforced on the action and fails open on an unreadable attribute in AshAuthentication
Summary
Authentication Bypass by Primary Weakness vulnerability in team-alembic AshAuthentication allows an unconfirmed user to obtain a session, defeating a mandatory email confirmation requirement.
AshAuthentication.Strategy.Password.Actions.check_user/2 decides whether the attribute named by require_confirmed_with is set using a bare is_nil(Map.get(user, value)). When that attribute is not selected on the loaded record Map.get/2 returns %Ash.NotLoaded{}, and when a field policy denies it for the current actor it returns %Ash.ForbiddenField{}. Neither is nil, so the rejection branch is skipped and sign-i
require_confirmed_with is enforced in two places, and neither holds in every configuration. sign_in_with_token and register are checked only inside AshAuthentication.Strategy.Password.Actions, not on the action itself, so any caller that invokes the action directly skips the check. An API layer such as AshGraphql or AshJsonApi invokes the action directly, so this applies to the default configuration. Where a check does run it compares the confirmation attribute against nil. That attribute holds %Ash.NotLoaded{} or %Ash.ForbiddenField{} when it sets select_by_default?: false, when an API layer narrows the read's select, or when a field policy hides it from the sign-in actor. Neither struct is nil, so those configurations read every user as confirmed.
This issue affects ash_authentication: from 4.3.8 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:12 UTC
CWE
- CWE-305 - Authentication Bypass by Primary Weakness
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.3.8 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
7d37bc6e4df6697b5813d2f373f0fdb08f813f98 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-85500",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:12:03.493938Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:12:54.127Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/actions.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:check_user/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:sign_in_with_token/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:register/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.3.8",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/actions.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:check_user/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:sign_in_with_token/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.Actions\u0027:register/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "17f4c25a372d1778c9cc457759e6357570d83711",
"status": "unaffected"
},
{
"at": "1076639a9d40213088d110c79ba6735b8cc85b16",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "7d37bc6e4df6697b5813d2f373f0fdb08f813f98",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.3.8",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:24:17.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAuthentication Bypass by Primary Weakness vulnerability in team-alembic AshAuthentication allows an unconfirmed user to obtain a session, defeating a mandatory email confirmation requirement.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Strategy.Password.Actions.check_user/2\u003c/code\u003e decides whether the attribute named by \u003ccode\u003erequire_confirmed_with\u003c/code\u003e is set using a bare \u003ccode\u003eis_nil(Map.get(user, value))\u003c/code\u003e. When that attribute is not selected on the loaded record \u003ccode\u003eMap.get/2\u003c/code\u003e returns \u003ccode\u003e%Ash.NotLoaded{}\u003c/code\u003e, and when a field policy denies it for the current actor it returns \u003ccode\u003e%Ash.ForbiddenField{}\u003c/code\u003e. Neither is \u003ccode\u003enil\u003c/code\u003e, so the rejection branch is skipped and sign-i\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003erequire_confirmed_with\u003c/code\u003e is enforced in two places, and neither holds in every\nconfiguration. \u003ccode\u003esign_in_with_token\u003c/code\u003e and \u003ccode\u003eregister\u003c/code\u003e are checked only inside\n\u003ccode\u003eAshAuthentication.Strategy.Password.Actions\u003c/code\u003e, not on the action itself, so any caller\nthat invokes the action directly skips the check. An API layer such as \u003ccode\u003eAshGraphql\u003c/code\u003e or\n\u003ccode\u003eAshJsonApi\u003c/code\u003e invokes the action directly, so this applies to the default configuration.\nWhere a check does run it compares the confirmation attribute against \u003ccode\u003enil\u003c/code\u003e. That\nattribute holds \u003ccode\u003e%Ash.NotLoaded{}\u003c/code\u003e or \u003ccode\u003e%Ash.ForbiddenField{}\u003c/code\u003e when it sets\n\u003ccode\u003eselect_by_default?: false\u003c/code\u003e, when an API layer narrows the read\u0027s \u003ccode\u003eselect\u003c/code\u003e, or when a\nfield policy hides it from the sign-in actor. Neither struct is \u003ccode\u003enil\u003c/code\u003e, so those\nconfigurations read every user as confirmed.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.3.8 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Authentication Bypass by Primary Weakness vulnerability in team-alembic AshAuthentication allows an unconfirmed user to obtain a session, defeating a mandatory email confirmation requirement.\n\n`AshAuthentication.Strategy.Password.Actions.check_user/2` decides whether the attribute named by `require_confirmed_with` is set using a bare `is_nil(Map.get(user, value))`. When that attribute is not selected on the loaded record `Map.get/2` returns `%Ash.NotLoaded{}`, and when a field policy denies it for the current actor it returns `%Ash.ForbiddenField{}`. Neither is `nil`, so the rejection branch is skipped and sign-i\n\n`require_confirmed_with` is enforced in two places, and neither holds in every\nconfiguration. `sign_in_with_token` and `register` are checked only inside\n`AshAuthentication.Strategy.Password.Actions`, not on the action itself, so any caller\nthat invokes the action directly skips the check. An API layer such as `AshGraphql` or\n`AshJsonApi` invokes the action directly, so this applies to the default configuration.\nWhere a check does run it compares the confirmation attribute against `nil`. That\nattribute holds `%Ash.NotLoaded{}` or `%Ash.ForbiddenField{}` when it sets\n`select_by_default?: false`, when an API layer narrows the read\u0027s `select`, or when a\nfield policy hides it from the sign-in actor. Neither struct is `nil`, so those\nconfigurations read every user as confirmed.\n\nThis issue affects ash_authentication: from 4.3.8 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Authentication Bypass by Primary Weakness vulnerability in team-alembic AshAuthentication allows an unconfirmed user to obtain a session, defeating a mandatory email confirmation requirement.\n\nAshAuthentication.Strategy.Password.Actions.check_user/2 decides whether the attribute named by require_confirmed_with is set using a bare is_nil(Map.get(user, value)). When that attribute is not selected on the loaded record Map.get/2 returns %Ash.NotLoaded{}, and when a field policy denies it for the current actor it returns %Ash.ForbiddenField{}. Neither is nil, so the rejection branch is skipped and sign-i\n\nrequire_confirmed_with is enforced in two places, and neither holds in every configuration. sign_in_with_token and register are checked only inside AshAuthentication.Strategy.Password.Actions, not on the action itself, so any caller that invokes the action directly skips the check. An API layer such as AshGraphql or AshJsonApi invokes the action directly, so this applies to the default configuration. Where a check does run it compares the confirmation attribute against nil. That attribute holds %Ash.NotLoaded{} or %Ash.ForbiddenField{} when it sets select_by_default?: false, when an API layer narrows the read\u0027s select, or when a field policy hides it from the sign-in actor. Neither struct is nil, so those configurations read every user as confirmed.\n\nThis issue affects ash_authentication: from 4.3.8 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-115",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-115 Authentication Bypass"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-305",
"description": "CWE-305 Authentication Bypass by Primary Weakness",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:43.000Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-fc47-6pgw-wh22"
},
{
"name": "EEF CNA record for CVE-2026-85500",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-85500.html"
},
{
"name": "OSV record EEF-CVE-2026-85500",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-85500"
},
{
"name": "Introducing commit 7d37bc6 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/7d37bc6e4df6697b5813d2f373f0fdb08f813f98"
},
{
"name": "Fix commit 17f4c25 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/17f4c25a372d1778c9cc457759e6357570d83711"
},
{
"name": "Fix commit 1076639 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/1076639a9d40213088d110c79ba6735b8cc85b16"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "`require_confirmed_with` is not enforced on the action and fails open on an unreadable attribute in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-85500",
"datePublished": "2026-09-17T13:09:43.000Z",
"dateReserved": "2026-09-07T23:45:01.895Z",
"dateUpdated": "2026-09-17T18:12:54.127Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-86533 (GCVE-0-2026-86533)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:17
VLAI
EPSS
VEX
Title
Revoked session accepted because the session jti is never checked in AshAuthentication and AshAuthentication Phoenix
Summary
Insufficient Session Expiration vulnerability in team-alembic AshAuthentication and AshAuthentication Phoenix allows a revoked session to remain fully authenticated.
A resource configured with session_identifier :jti and require_token_presence_for_authentication? disabled stores its session value as <jti>:<subject>. The jti is there so that signing out can revoke that one session. Neither reader consults it: AshAuthentication.Plug.Helpers.authenticate_resource_from_session/4 and AshAuthentication.Phoenix.LiveSession.on_mount/4 both split the value with split_identifier/2, discard the jti and pass the bare subject to AshAuthentication.subject_to_user/3, which reloads the record. The token-presence branch of each function does check its token, calling AshAuthentication.TokenResource.Actions.get_token/3 with the jti and the purpose user. Because the revocation record is never read, neither its revoked state nor its expiry constrains the session, so a session captured before sign-out keeps working.
This issue affects ash_authentication: from 4.9.1 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14; ash_authentication_phoenix: from 2.10.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:13 UTC
CWE
- CWE-613 - Insufficient Session Expiration
Assigner
References
10 references
Impacted products
4 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.9.1 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
fcaeb73f76f8f2e9aef8bf637690d2a20dd97596 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication_phoenix |
Affected:
2.10.0 , < 2.17.4
(semver)
Affected: 3.0.0-rc.0 , < 3.0.0-rc.11 (semver) cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication_phoenix |
Affected:
a3253fb4fc7145aeb403537af1c24d3a8d51ffb1 , < *
(git)
Affected: 0135217e34e621dac79ae3d9559aeee49304b0aa , < * (git) cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:* |
Date Public
2026-09-17 13:09
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-86533",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:13:50.422619Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:17:21.199Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Plug.Helpers\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/plug/helpers.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:retrieve_from_session/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:authenticate_resource_from_session/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.9.1",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Plug.Helpers\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/plug/helpers.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:retrieve_from_session/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Plug.Helpers\u0027:authenticate_resource_from_session/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "a3f49f758f013d2ff086dd9c5ef2d94e921711b4",
"status": "unaffected"
},
{
"at": "e28e911caa9728d76329afdb0fb26742ffe4eeef",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "fcaeb73f76f8f2e9aef8bf637690d2a20dd97596",
"versionType": "git"
}
]
},
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.LiveSession\u0027"
],
"packageName": "ash_authentication_phoenix",
"packageURL": "pkg:hex/ash_authentication_phoenix",
"product": "ash_authentication_phoenix",
"programFiles": [
"lib/ash_authentication_phoenix/live_session.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.LiveSession\u0027:on_mount/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication_phoenix",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "2.17.4",
"status": "affected",
"version": "2.10.0",
"versionType": "semver"
},
{
"lessThan": "3.0.0-rc.11",
"status": "affected",
"version": "3.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.LiveSession\u0027"
],
"packageName": "team-alembic/ash_authentication_phoenix",
"packageURL": "pkg:github/team-alembic/ash_authentication_phoenix",
"product": "ash_authentication_phoenix",
"programFiles": [
"lib/ash_authentication_phoenix/live_session.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.LiveSession\u0027:on_mount/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication_phoenix",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "f7ab005a2aac09707a25521653c94893d328cc52",
"status": "unaffected"
},
{
"at": "0135217e34e621dac79ae3d9559aeee49304b0aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "a3253fb4fc7145aeb403537af1c24d3a8d51ffb1",
"versionType": "git"
},
{
"changes": [
{
"at": "f7ab005a2aac09707a25521653c94893d328cc52",
"status": "unaffected"
},
{
"at": "0135217e34e621dac79ae3d9559aeee49304b0aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "0135217e34e621dac79ae3d9559aeee49304b0aa",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.9.1",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*",
"versionEndExcluding": "2.17.4",
"versionStartIncluding": "2.10.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.0.0-rc.11",
"versionStartIncluding": "3.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:52:39.000Z",
"datePublic": "2026-09-17T13:09:38.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eInsufficient Session Expiration vulnerability in team-alembic AshAuthentication and AshAuthentication Phoenix allows a revoked session to remain fully authenticated.\u003c/p\u003e\n\u003cp\u003eA resource configured with \u003ccode\u003esession_identifier :jti\u003c/code\u003e and \u003ccode\u003erequire_token_presence_for_authentication?\u003c/code\u003e disabled stores its session value as \u003ccode\u003e\u0026lt;jti\u0026gt;:\u0026lt;subject\u0026gt;\u003c/code\u003e. The \u003ccode\u003ejti\u003c/code\u003e is there so that signing out can revoke that one session. Neither reader consults it: \u003ccode\u003eAshAuthentication.Plug.Helpers.authenticate_resource_from_session/4\u003c/code\u003e and \u003ccode\u003eAshAuthentication.Phoenix.LiveSession.on_mount/4\u003c/code\u003e both split the value with \u003ccode\u003esplit_identifier/2\u003c/code\u003e, discard the \u003ccode\u003ejti\u003c/code\u003e and pass the bare subject to \u003ccode\u003eAshAuthentication.subject_to_user/3\u003c/code\u003e, which reloads the record. The token-presence branch of each function does check its token, calling \u003ccode\u003eAshAuthentication.TokenResource.Actions.get_token/3\u003c/code\u003e with the \u003ccode\u003ejti\u003c/code\u003e and the purpose \u003ccode\u003euser\u003c/code\u003e. Because the revocation record is never read, neither its revoked state nor its expiry constrains the session, so a session captured before sign-out keeps working.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.9.1 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14; ash_authentication_phoenix: from 2.10.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Insufficient Session Expiration vulnerability in team-alembic AshAuthentication and AshAuthentication Phoenix allows a revoked session to remain fully authenticated.\n\nA resource configured with `session_identifier :jti` and `require_token_presence_for_authentication?` disabled stores its session value as `\u003cjti\u003e:\u003csubject\u003e`. The `jti` is there so that signing out can revoke that one session. Neither reader consults it: `AshAuthentication.Plug.Helpers.authenticate_resource_from_session/4` and `AshAuthentication.Phoenix.LiveSession.on_mount/4` both split the value with `split_identifier/2`, discard the `jti` and pass the bare subject to `AshAuthentication.subject_to_user/3`, which reloads the record. The token-presence branch of each function does check its token, calling `AshAuthentication.TokenResource.Actions.get_token/3` with the `jti` and the purpose `user`. Because the revocation record is never read, neither its revoked state nor its expiry constrains the session, so a session captured before sign-out keeps working.\n\nThis issue affects ash_authentication: from 4.9.1 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14; ash_authentication_phoenix: from 2.10.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11."
}
],
"value": "Insufficient Session Expiration vulnerability in team-alembic AshAuthentication and AshAuthentication Phoenix allows a revoked session to remain fully authenticated.\n\nA resource configured with session_identifier :jti and require_token_presence_for_authentication? disabled stores its session value as \u003cjti\u003e:\u003csubject\u003e. The jti is there so that signing out can revoke that one session. Neither reader consults it: AshAuthentication.Plug.Helpers.authenticate_resource_from_session/4 and AshAuthentication.Phoenix.LiveSession.on_mount/4 both split the value with split_identifier/2, discard the jti and pass the bare subject to AshAuthentication.subject_to_user/3, which reloads the record. The token-presence branch of each function does check its token, calling AshAuthentication.TokenResource.Actions.get_token/3 with the jti and the purpose user. Because the revocation record is never read, neither its revoked state nor its expiry constrains the session, so a session captured before sign-out keeps working.\n\nThis issue affects ash_authentication: from 4.9.1 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14; ash_authentication_phoenix: from 2.10.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11."
}
],
"impacts": [
{
"capecId": "CAPEC-60",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-60 Reusing Session IDs (aka Session Replay)"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-613",
"description": "CWE-613 Insufficient Session Expiration",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T14:05:29.472Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/security/advisories/GHSA-m6x4-4gvp-xwjr"
},
{
"name": "EEF CNA record for CVE-2026-86533",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-86533.html"
},
{
"name": "OSV record EEF-CVE-2026-86533",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-86533"
},
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-w374-hvrx-66hg"
},
{
"name": "Introducing commit fcaeb73 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/fcaeb73f76f8f2e9aef8bf637690d2a20dd97596"
},
{
"name": "Fix commit a3f49f7 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/a3f49f758f013d2ff086dd9c5ef2d94e921711b4"
},
{
"name": "Fix commit e28e911 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/e28e911caa9728d76329afdb0fb26742ffe4eeef"
},
{
"name": "Introducing commit a3253fb in team-alembic/ash_authentication_phoenix",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/a3253fb4fc7145aeb403537af1c24d3a8d51ffb1"
},
{
"name": "Introducing commit 0135217 in team-alembic/ash_authentication_phoenix",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/0135217e34e621dac79ae3d9559aeee49304b0aa"
},
{
"name": "Fix commit f7ab005 in team-alembic/ash_authentication_phoenix",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/f7ab005a2aac09707a25521653c94893d328cc52"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Revoked session accepted because the session jti is never checked in AshAuthentication and AshAuthentication Phoenix"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-86533",
"datePublished": "2026-09-17T13:09:37.963Z",
"dateReserved": "2026-09-11T18:00:02.036Z",
"dateUpdated": "2026-09-17T18:17:21.199Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-81632 (GCVE-0-2026-81632)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:29
VLAI
EPSS
VEX
Title
Single-use sign-in token placed in a redirect query string in AshAuthenticationPhoenix
Summary
Use of HTTP Request With Sensitive Query String vulnerability in team-alembic AshAuthenticationPhoenix allows someone able to read access logs, proxy logs or browser history to recover a single-use sign-in token and authenticate as its owner.
After a successful password sign-in, AshAuthentication.Phoenix.Components.Password.SignInForm builds the sign_in_with_token path with the freshly issued user.__metadata__.token as a query parameter and redirects the browser to it with a GET. The token therefore travels in the request line, where web servers, reverse proxies, request telemetry and the browser's own history record it, all of which outlive the request and are ordinarily less protected than session storage. The redirect destination is restricted to a local path, so this is not an open redirect; the exposure is the retention of a live credential.
This issue affects ash_authentication_phoenix: from 1.7.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11; ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:29 UTC
CWE
- CWE-598 - Use of HTTP Request With Sensitive Query String
Assigner
References
10 references
Impacted products
4 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication_phoenix |
Affected:
1.7.0 , < 2.17.4
(semver)
Affected: 3.0.0-rc.0 , < 3.0.0-rc.11 (semver) cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication_phoenix |
Affected:
903f3a386e1aba2f7b070187ef6f31215a92bdfd , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
3.10.5 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
eca8cadea0f1595ed2c10a0c177b1da9aa9e5269 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-81632",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:29:05.558007Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:29:20.271Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027"
],
"packageName": "ash_authentication_phoenix",
"packageURL": "pkg:hex/ash_authentication_phoenix",
"product": "ash_authentication_phoenix",
"programFiles": [
"lib/ash_authentication_phoenix/components/password/sign_in_form.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:handle_event/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:get_redirect_path/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:get_auth_path_params/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication_phoenix",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "2.17.4",
"status": "affected",
"version": "1.7.0",
"versionType": "semver"
},
{
"lessThan": "3.0.0-rc.11",
"status": "affected",
"version": "3.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027"
],
"packageName": "team-alembic/ash_authentication_phoenix",
"packageURL": "pkg:github/team-alembic/ash_authentication_phoenix",
"product": "ash_authentication_phoenix",
"programFiles": [
"lib/ash_authentication_phoenix/components/password/sign_in_form.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:handle_event/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:get_redirect_path/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Components.Password.SignInForm\u0027:get_auth_path_params/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication_phoenix",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "920257d0460b9c7cbb42a83d0888c10f4eeeb88a",
"status": "unaffected"
},
{
"at": "ff5ad8737748afed9cdfde3ec3a05b8a4702a742",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "903f3a386e1aba2f7b070187ef6f31215a92bdfd",
"versionType": "git"
}
]
},
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "3.10.5",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "bbf345c1bb7aa28bce5dd856ac0ed2427f103859",
"status": "unaffected"
},
{
"at": "8d8ddd25c69b669a92a701af74bff42e1aada998",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "eca8cadea0f1595ed2c10a0c177b1da9aa9e5269",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*",
"versionEndExcluding": "2.17.4",
"versionStartIncluding": "1.7.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication_phoenix:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.0.0-rc.11",
"versionStartIncluding": "3.0.0-rc.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "3.10.5",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:51:56.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUse of HTTP Request With Sensitive Query String vulnerability in team-alembic AshAuthenticationPhoenix allows someone able to read access logs, proxy logs or browser history to recover a single-use sign-in token and authenticate as its owner.\u003c/p\u003e\n\u003cp\u003eAfter a successful password sign-in, \u003ccode\u003eAshAuthentication.Phoenix.Components.Password.SignInForm\u003c/code\u003e builds the \u003ccode\u003esign_in_with_token\u003c/code\u003e path with the freshly issued \u003ccode\u003euser.__metadata__.token\u003c/code\u003e as a query parameter and redirects the browser to it with a GET. The token therefore travels in the request line, where web servers, reverse proxies, request telemetry and the browser\u0027s own history record it, all of which outlive the request and are ordinarily less protected than session storage. The redirect destination is restricted to a local path, so this is not an open redirect; the exposure is the retention of a live credential.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication_phoenix: from 1.7.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11; ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Use of HTTP Request With Sensitive Query String vulnerability in team-alembic AshAuthenticationPhoenix allows someone able to read access logs, proxy logs or browser history to recover a single-use sign-in token and authenticate as its owner.\n\nAfter a successful password sign-in, `AshAuthentication.Phoenix.Components.Password.SignInForm` builds the `sign_in_with_token` path with the freshly issued `user.__metadata__.token` as a query parameter and redirects the browser to it with a GET. The token therefore travels in the request line, where web servers, reverse proxies, request telemetry and the browser\u0027s own history record it, all of which outlive the request and are ordinarily less protected than session storage. The redirect destination is restricted to a local path, so this is not an open redirect; the exposure is the retention of a live credential.\n\nThis issue affects ash_authentication_phoenix: from 1.7.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11; ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Use of HTTP Request With Sensitive Query String vulnerability in team-alembic AshAuthenticationPhoenix allows someone able to read access logs, proxy logs or browser history to recover a single-use sign-in token and authenticate as its owner.\n\nAfter a successful password sign-in, AshAuthentication.Phoenix.Components.Password.SignInForm builds the sign_in_with_token path with the freshly issued user.__metadata__.token as a query parameter and redirects the browser to it with a GET. The token therefore travels in the request line, where web servers, reverse proxies, request telemetry and the browser\u0027s own history record it, all of which outlive the request and are ordinarily less protected than session storage. The redirect destination is restricted to a local path, so this is not an open redirect; the exposure is the retention of a live credential.\n\nThis issue affects ash_authentication_phoenix: from 1.7.0 before 2.17.4 and from 3.0.0-rc.0 before 3.0.0-rc.11; ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-150",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-150 Collect Data from Common Resource Locations"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 7.2,
"baseSeverity": "HIGH",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-598",
"description": "CWE-598 Use of HTTP Request With Sensitive Query String",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:31.601Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/security/advisories/GHSA-8jh5-339h-mqx9"
},
{
"name": "EEF CNA record for CVE-2026-81632",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-81632.html"
},
{
"name": "OSV record EEF-CVE-2026-81632",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-81632"
},
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-j726-59hm-r46r"
},
{
"name": "Introducing commit 903f3a3 in team-alembic/ash_authentication_phoenix",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/903f3a386e1aba2f7b070187ef6f31215a92bdfd"
},
{
"name": "Fix commit 920257d in team-alembic/ash_authentication_phoenix",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/920257d0460b9c7cbb42a83d0888c10f4eeeb88a"
},
{
"name": "Fix commit ff5ad87 in team-alembic/ash_authentication_phoenix",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication_phoenix/commit/ff5ad8737748afed9cdfde3ec3a05b8a4702a742"
},
{
"name": "Introducing commit eca8cad in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/eca8cadea0f1595ed2c10a0c177b1da9aa9e5269"
},
{
"name": "Fix commit bbf345c in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/bbf345c1bb7aa28bce5dd856ac0ed2427f103859"
},
{
"name": "Fix commit 8d8ddd2 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/8d8ddd25c69b669a92a701af74bff42e1aada998"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Single-use sign-in token placed in a redirect query string in AshAuthenticationPhoenix"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-81632",
"datePublished": "2026-09-17T13:09:31.601Z",
"dateReserved": "2026-09-11T18:45:01.476Z",
"dateUpdated": "2026-09-17T18:29:20.271Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-80218 (GCVE-0-2026-80218)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:28
VLAI
EPSS
VEX
Title
Sign-in token minted for one resource accepted by another in AshAuthentication
Summary
Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker holding a sign-in token for one authenticated resource to be signed in as a user of a different resource.
AshAuthentication.Strategy.Password.SignInWithTokenPreparation.extract_primary_keys_from_subject/2 parses the JWT sub claim (for example user?id=1) with URI.parse/1 and keeps only its query string, discarding the path segment that names the subject the token was issued for. Nothing else restores that binding: AshAuthentication.Jwt.verify/3 checks the signature, exp, nbf, jti and the library-version claims, the purpose check only requires sign_in, and the remaining comparison is over primary-key field names, which are identical across resources. The WebAuthn sign-in and remember-me preparations carry copies of the same helper and drop the path in the same way. The magic link sign-in path pins the subject name against the resource and is not affected.
This issue affects ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:28 UTC
CWE
- CWE-287 - Improper Authentication
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
3.10.5 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
eca8cadea0f1595ed2c10a0c177b1da9aa9e5269 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-80218",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:28:40.896413Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:28:47.571Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.SignInWithTokenPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.WebAuthn.SignInWithTokenPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.RememberMe.SignInPreparation\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/sign_in_with_token_preparation.ex",
"lib/ash_authentication/strategies/webauthn/sign_in_with_token_preparation.ex",
"lib/ash_authentication/strategies/remember_me/sign_in_preparation.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.SignInWithTokenPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.WebAuthn.SignInWithTokenPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.RememberMe.SignInPreparation\u0027:prepare/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "3.10.5",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.SignInWithTokenPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.WebAuthn.SignInWithTokenPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.RememberMe.SignInPreparation\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/sign_in_with_token_preparation.ex",
"lib/ash_authentication/strategies/webauthn/sign_in_with_token_preparation.ex",
"lib/ash_authentication/strategies/remember_me/sign_in_preparation.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.SignInWithTokenPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.WebAuthn.SignInWithTokenPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.RememberMe.SignInPreparation\u0027:prepare/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "2640e1872e1fef4e4606e601bf00102cff784c03",
"status": "unaffected"
},
{
"at": "7baac243ca651eee127a84d672eee3fcff42e598",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "eca8cadea0f1595ed2c10a0c177b1da9aa9e5269",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "3.10.5",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:34:31.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Authentication vulnerability in team-alembic AshAuthentication allows an attacker holding a sign-in token for one authenticated resource to be signed in as a user of a different resource.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Strategy.Password.SignInWithTokenPreparation.extract_primary_keys_from_subject/2\u003c/code\u003e parses the JWT \u003ccode\u003esub\u003c/code\u003e claim (for example \u003ccode\u003euser?id=1\u003c/code\u003e) with \u003ccode\u003eURI.parse/1\u003c/code\u003e and keeps only its query string, discarding the path segment that names the subject the token was issued for. Nothing else restores that binding: \u003ccode\u003eAshAuthentication.Jwt.verify/3\u003c/code\u003e checks the signature, \u003ccode\u003eexp\u003c/code\u003e, \u003ccode\u003enbf\u003c/code\u003e, \u003ccode\u003ejti\u003c/code\u003e and the library-version claims, the purpose check only requires \u003ccode\u003esign_in\u003c/code\u003e, and the remaining comparison is over primary-key field names, which are identical across resources. The WebAuthn sign-in and remember-me preparations carry copies of the same helper and drop the path in the same way. The magic link sign-in path pins the subject name against the resource and is not affected.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker holding a sign-in token for one authenticated resource to be signed in as a user of a different resource.\n\n`AshAuthentication.Strategy.Password.SignInWithTokenPreparation.extract_primary_keys_from_subject/2` parses the JWT `sub` claim (for example `user?id=1`) with `URI.parse/1` and keeps only its query string, discarding the path segment that names the subject the token was issued for. Nothing else restores that binding: `AshAuthentication.Jwt.verify/3` checks the signature, `exp`, `nbf`, `jti` and the library-version claims, the purpose check only requires `sign_in`, and the remaining comparison is over primary-key field names, which are identical across resources. The WebAuthn sign-in and remember-me preparations carry copies of the same helper and drop the path in the same way. The magic link sign-in path pins the subject name against the resource and is not affected.\n\nThis issue affects ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Improper Authentication vulnerability in team-alembic AshAuthentication allows an attacker holding a sign-in token for one authenticated resource to be signed in as a user of a different resource.\n\nAshAuthentication.Strategy.Password.SignInWithTokenPreparation.extract_primary_keys_from_subject/2 parses the JWT sub claim (for example user?id=1) with URI.parse/1 and keeps only its query string, discarding the path segment that names the subject the token was issued for. Nothing else restores that binding: AshAuthentication.Jwt.verify/3 checks the signature, exp, nbf, jti and the library-version claims, the purpose check only requires sign_in, and the remaining comparison is over primary-key field names, which are identical across resources. The WebAuthn sign-in and remember-me preparations carry copies of the same helper and drop the path in the same way. The magic link sign-in path pins the subject name against the resource and is not affected.\n\nThis issue affects ash_authentication: from 3.10.5 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-151",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-151 Identity Spoofing"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 7.6,
"baseSeverity": "HIGH",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-287",
"description": "CWE-287 Improper Authentication",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:25.585Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-3pr8-f99q-86hp"
},
{
"name": "EEF CNA record for CVE-2026-80218",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-80218.html"
},
{
"name": "OSV record EEF-CVE-2026-80218",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-80218"
},
{
"name": "Introducing commit eca8cad in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/eca8cadea0f1595ed2c10a0c177b1da9aa9e5269"
},
{
"name": "Fix commit 2640e18 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/2640e1872e1fef4e4606e601bf00102cff784c03"
},
{
"name": "Fix commit 7baac24 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/7baac243ca651eee127a84d672eee3fcff42e598"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Sign-in token minted for one resource accepted by another in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-80218",
"datePublished": "2026-09-17T13:09:25.585Z",
"dateReserved": "2026-09-11T18:30:01.333Z",
"dateUpdated": "2026-09-17T18:28:47.571Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-78223 (GCVE-0-2026-78223)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:28
VLAI
EPSS
VEX
Title
Token revocation record built from unverified JWT claims in AshAuthentication
Summary
Improper Verification of Cryptographic Signature vulnerability in team-alembic AshAuthentication allows a caller of the token revocation action to neutralise a revocation or write arbitrary rows into the token resource.
AshAuthentication.TokenResource.RevokeTokenChange.change/3 reads the :token argument and decodes it with AshAuthentication.Jwt.peek/1, which delegates to Joken.peek_claims/1 and performs no signature check, unlike Jwt.verify/4. The jti, exp and sub claims it returns are written straight onto the revocation record, guarded only by byte_size(token) > 0. Because expires_at derives from the attacker-chosen exp, a forged copy of a genuine token that keeps the real jti but backdates exp yields a revocation row that is already expired: expunge_expired removes it and the genuine token passes revoked? again. Arbitrary jti and sub values can be inserted the same way.
This issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:28 UTC
CWE
- CWE-347 - Improper Verification of Cryptographic Signature
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
0.2.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
a939dde9b917c072cdf10c4b0913a9886a4b0231 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-78223",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:28:12.763636Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:28:20.821Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.TokenResource.RevokeTokenChange\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/token_resource/revoke_token_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.TokenResource.RevokeTokenChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "0.2.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.TokenResource.RevokeTokenChange\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/token_resource/revoke_token_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.TokenResource.RevokeTokenChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "344cebb12faf68e648d3283394073ba0c0f78459",
"status": "unaffected"
},
{
"at": "eb86353fe5a547c5ff5fd9af0e2c212518c31c9b",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "a939dde9b917c072cdf10c4b0913a9886a4b0231",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "0.2.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:31:49.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Verification of Cryptographic Signature vulnerability in team-alembic AshAuthentication allows a caller of the token revocation action to neutralise a revocation or write arbitrary rows into the token resource.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.TokenResource.RevokeTokenChange.change/3\u003c/code\u003e reads the \u003ccode\u003e:token\u003c/code\u003e argument and decodes it with \u003ccode\u003eAshAuthentication.Jwt.peek/1\u003c/code\u003e, which delegates to \u003ccode\u003eJoken.peek_claims/1\u003c/code\u003e and performs no signature check, unlike \u003ccode\u003eJwt.verify/4\u003c/code\u003e. The \u003ccode\u003ejti\u003c/code\u003e, \u003ccode\u003eexp\u003c/code\u003e and \u003ccode\u003esub\u003c/code\u003e claims it returns are written straight onto the revocation record, guarded only by \u003ccode\u003ebyte_size(token) \u0026gt; 0\u003c/code\u003e. Because \u003ccode\u003eexpires_at\u003c/code\u003e derives from the attacker-chosen \u003ccode\u003eexp\u003c/code\u003e, a forged copy of a genuine token that keeps the real \u003ccode\u003ejti\u003c/code\u003e but backdates \u003ccode\u003eexp\u003c/code\u003e yields a revocation row that is already expired: \u003ccode\u003eexpunge_expired\u003c/code\u003e removes it and the genuine token passes \u003ccode\u003erevoked?\u003c/code\u003e again. Arbitrary \u003ccode\u003ejti\u003c/code\u003e and \u003ccode\u003esub\u003c/code\u003e values can be inserted the same way.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Verification of Cryptographic Signature vulnerability in team-alembic AshAuthentication allows a caller of the token revocation action to neutralise a revocation or write arbitrary rows into the token resource.\n\n`AshAuthentication.TokenResource.RevokeTokenChange.change/3` reads the `:token` argument and decodes it with `AshAuthentication.Jwt.peek/1`, which delegates to `Joken.peek_claims/1` and performs no signature check, unlike `Jwt.verify/4`. The `jti`, `exp` and `sub` claims it returns are written straight onto the revocation record, guarded only by `byte_size(token) \u003e 0`. Because `expires_at` derives from the attacker-chosen `exp`, a forged copy of a genuine token that keeps the real `jti` but backdates `exp` yields a revocation row that is already expired: `expunge_expired` removes it and the genuine token passes `revoked?` again. Arbitrary `jti` and `sub` values can be inserted the same way.\n\nThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Improper Verification of Cryptographic Signature vulnerability in team-alembic AshAuthentication allows a caller of the token revocation action to neutralise a revocation or write arbitrary rows into the token resource.\n\nAshAuthentication.TokenResource.RevokeTokenChange.change/3 reads the :token argument and decodes it with AshAuthentication.Jwt.peek/1, which delegates to Joken.peek_claims/1 and performs no signature check, unlike Jwt.verify/4. The jti, exp and sub claims it returns are written straight onto the revocation record, guarded only by byte_size(token) \u003e 0. Because expires_at derives from the attacker-chosen exp, a forged copy of a genuine token that keeps the real jti but backdates exp yields a revocation row that is already expired: expunge_expired removes it and the genuine token passes revoked? again. Arbitrary jti and sub values can be inserted the same way.\n\nThis issue affects ash_authentication: from 0.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-475",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-475 Signature Spoofing by Improper Validation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 6.9,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-347",
"description": "CWE-347 Improper Verification of Cryptographic Signature",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:19.591Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-mfwg-5cpf-px58"
},
{
"name": "EEF CNA record for CVE-2026-78223",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-78223.html"
},
{
"name": "OSV record EEF-CVE-2026-78223",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-78223"
},
{
"name": "Introducing commit a939dde in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/a939dde9b917c072cdf10c4b0913a9886a4b0231"
},
{
"name": "Fix commit 344cebb in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/344cebb12faf68e648d3283394073ba0c0f78459"
},
{
"name": "Fix commit eb86353 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/eb86353fe5a547c5ff5fd9af0e2c212518c31c9b"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Token revocation record built from unverified JWT claims in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-78223",
"datePublished": "2026-09-17T13:09:19.591Z",
"dateReserved": "2026-09-11T18:30:01.328Z",
"dateUpdated": "2026-09-17T18:28:20.821Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-86522 (GCVE-0-2026-86522)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:27
VLAI
EPSS
VEX
Title
Log injection via an unescaped password reset identity in AshAuthentication
Summary
Improper Output Neutralization for Logs vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to forge application log entries by submitting a password reset identity containing newlines or control characters.
AshAuthentication.Strategy.Password.RequestPasswordReset.run/3 interpolates the identity argument, the email or username taken straight from the reset request, into its Logger.warning/1 heredocs without escaping, truncating or type-restricting it. The resource logged beside it is passed through inspect/1, which would have neutralized the value. A newline in the identity therefore ends the log record, and everything after it is written as a line of its own, so an attacker chooses the severity tag and the content of entries that appear to have come from the application.
This issue affects ash_authentication: from 4.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:27 UTC
CWE
- CWE-117 - Improper Output Neutralization for Logs
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.2.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
3954f277929712755aef57a4a3a821688f121316 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-86522",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:27:45.711185Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:27:51.681Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.RequestPasswordReset\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/request_password_reset.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.RequestPasswordReset\u0027:run/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.2.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.Password.RequestPasswordReset\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/password/request_password_reset.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.Password.RequestPasswordReset\u0027:run/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "fd19358bf0eee53ef13dcf17cc499bd4fb393981",
"status": "unaffected"
},
{
"at": "57c7cc3236bef0fa9da19cb315414f216488866d",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "3954f277929712755aef57a4a3a821688f121316",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.2.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:26:23.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Output Neutralization for Logs vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to forge application log entries by submitting a password reset identity containing newlines or control characters.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Strategy.Password.RequestPasswordReset.run/3\u003c/code\u003e interpolates the \u003ccode\u003eidentity\u003c/code\u003e argument, the email or username taken straight from the reset request, into its \u003ccode\u003eLogger.warning/1\u003c/code\u003e heredocs without escaping, truncating or type-restricting it. The resource logged beside it is passed through \u003ccode\u003einspect/1\u003c/code\u003e, which would have neutralized the value. A newline in the identity therefore ends the log record, and everything after it is written as a line of its own, so an attacker chooses the severity tag and the content of entries that appear to have come from the application.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Output Neutralization for Logs vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to forge application log entries by submitting a password reset identity containing newlines or control characters.\n\n`AshAuthentication.Strategy.Password.RequestPasswordReset.run/3` interpolates the `identity` argument, the email or username taken straight from the reset request, into its `Logger.warning/1` heredocs without escaping, truncating or type-restricting it. The resource logged beside it is passed through `inspect/1`, which would have neutralized the value. A newline in the identity therefore ends the log record, and everything after it is written as a line of its own, so an attacker chooses the severity tag and the content of entries that appear to have come from the application.\n\nThis issue affects ash_authentication: from 4.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Improper Output Neutralization for Logs vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to forge application log entries by submitting a password reset identity containing newlines or control characters.\n\nAshAuthentication.Strategy.Password.RequestPasswordReset.run/3 interpolates the identity argument, the email or username taken straight from the reset request, into its Logger.warning/1 heredocs without escaping, truncating or type-restricting it. The resource logged beside it is passed through inspect/1, which would have neutralized the value. A newline in the identity therefore ends the log record, and everything after it is written as a line of its own, so an attacker chooses the severity tag and the content of entries that appear to have come from the application.\n\nThis issue affects ash_authentication: from 4.2.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-93",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-93 Log Injection-Tampering-Forging"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-117",
"description": "CWE-117 Improper Output Neutralization for Logs",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:11.572Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-wg7g-r393-vr3g"
},
{
"name": "EEF CNA record for CVE-2026-86522",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-86522.html"
},
{
"name": "OSV record EEF-CVE-2026-86522",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-86522"
},
{
"name": "Introducing commit 3954f27 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/3954f277929712755aef57a4a3a821688f121316"
},
{
"name": "Fix commit fd19358 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/fd19358bf0eee53ef13dcf17cc499bd4fb393981"
},
{
"name": "Fix commit 57c7cc3 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/57c7cc3236bef0fa9da19cb315414f216488866d"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Log injection via an unescaped password reset identity in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-86522",
"datePublished": "2026-09-17T13:09:11.572Z",
"dateReserved": "2026-09-07T22:30:01.279Z",
"dateUpdated": "2026-09-17T18:27:51.681Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-81637 (GCVE-0-2026-81637)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:26
VLAI
EPSS
VEX
Title
Replayable OAuth2 CSRF state retained after a failed callback in AshAuthentication
Summary
Insufficient Session Expiration vulnerability in team-alembic AshAuthentication allows an attacker who obtains a victim's OAuth2 state value to replay the callback and sign that victim into an attacker-controlled account.
AshAuthentication.Strategy.OAuth2.Plug.callback/2 clears the stored session_params through a rebinding step inside its with chain, conn <- delete_session(conn, session_key). Elixir evaluates the else block in the scope enclosing the with, so every failure path (the provider returning ?error=access_denied, an invalid code, a token-exchange error, or a registration or sign-in failure) reaches store_authentication_result/2 holding the original connection and the session entry is never removed. The value the module's own comment describes as protection against a CSRF-related attack is therefore consumed only when authentication succeeds, and survives a cancelled or failed attempt until the next request phase or session expiry.
This issue affects ash_authentication: from 0.6.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:26 UTC
CWE
- CWE-613 - Insufficient Session Expiration
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
0.6.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
c5f589058e04239263f50a1430eb17ea6d5dd1a2 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-81637",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:26:48.969731Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:26:58.389Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/oauth2/plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027:callback/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027:request/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "0.6.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/oauth2/plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027:callback/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.OAuth2.Plug\u0027:request/2"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "bd4352303bc9d72d007f6818775267585a4bcc2f",
"status": "unaffected"
},
{
"at": "d7f939cd02bd618bcaa304631846fa75ffc419d7",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "c5f589058e04239263f50a1430eb17ea6d5dd1a2",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "0.6.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
}
],
"dateAssigned": "2026-09-11T18:16:32.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eInsufficient Session Expiration vulnerability in team-alembic AshAuthentication allows an attacker who obtains a victim\u0027s OAuth2 \u003ccode\u003estate\u003c/code\u003e value to replay the callback and sign that victim into an attacker-controlled account.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Strategy.OAuth2.Plug.callback/2\u003c/code\u003e clears the stored \u003ccode\u003esession_params\u003c/code\u003e through a rebinding step inside its \u003ccode\u003ewith\u003c/code\u003e chain, \u003ccode\u003econn \u0026lt;- delete_session(conn, session_key)\u003c/code\u003e. Elixir evaluates the \u003ccode\u003eelse\u003c/code\u003e block in the scope enclosing the \u003ccode\u003ewith\u003c/code\u003e, so every failure path (the provider returning \u003ccode\u003e?error=access_denied\u003c/code\u003e, an invalid code, a token-exchange error, or a registration or sign-in failure) reaches \u003ccode\u003estore_authentication_result/2\u003c/code\u003e holding the original connection and the session entry is never removed. The value the module\u0027s own comment describes as protection against a CSRF-related attack is therefore consumed only when authentication succeeds, and survives a cancelled or failed attempt until the next request phase or session expiry.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 0.6.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Insufficient Session Expiration vulnerability in team-alembic AshAuthentication allows an attacker who obtains a victim\u0027s OAuth2 `state` value to replay the callback and sign that victim into an attacker-controlled account.\n\n`AshAuthentication.Strategy.OAuth2.Plug.callback/2` clears the stored `session_params` through a rebinding step inside its `with` chain, `conn \u003c- delete_session(conn, session_key)`. Elixir evaluates the `else` block in the scope enclosing the `with`, so every failure path (the provider returning `?error=access_denied`, an invalid code, a token-exchange error, or a registration or sign-in failure) reaches `store_authentication_result/2` holding the original connection and the session entry is never removed. The value the module\u0027s own comment describes as protection against a CSRF-related attack is therefore consumed only when authentication succeeds, and survives a cancelled or failed attempt until the next request phase or session expiry.\n\nThis issue affects ash_authentication: from 0.6.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Insufficient Session Expiration vulnerability in team-alembic AshAuthentication allows an attacker who obtains a victim\u0027s OAuth2 state value to replay the callback and sign that victim into an attacker-controlled account.\n\nAshAuthentication.Strategy.OAuth2.Plug.callback/2 clears the stored session_params through a rebinding step inside its with chain, conn \u003c- delete_session(conn, session_key). Elixir evaluates the else block in the scope enclosing the with, so every failure path (the provider returning ?error=access_denied, an invalid code, a token-exchange error, or a registration or sign-in failure) reaches store_authentication_result/2 holding the original connection and the session entry is never removed. The value the module\u0027s own comment describes as protection against a CSRF-related attack is therefore consumed only when authentication succeeds, and survives a cancelled or failed attempt until the next request phase or session expiry.\n\nThis issue affects ash_authentication: from 0.6.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-60",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-60 Reusing Session IDs (aka Session Replay)"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "HIGH",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 2.3,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "PASSIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-613",
"description": "CWE-613 Insufficient Session Expiration",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:06.571Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-3vcj-gxx8-3p44"
},
{
"name": "EEF CNA record for CVE-2026-81637",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-81637.html"
},
{
"name": "OSV record EEF-CVE-2026-81637",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-81637"
},
{
"name": "Introducing commit c5f5890 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/c5f589058e04239263f50a1430eb17ea6d5dd1a2"
},
{
"name": "Fix commit bd43523 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/bd4352303bc9d72d007f6818775267585a4bcc2f"
},
{
"name": "Fix commit d7f939c in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/d7f939cd02bd618bcaa304631846fa75ffc419d7"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Replayable OAuth2 CSRF state retained after a failed callback in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-81637",
"datePublished": "2026-09-17T13:09:06.571Z",
"dateReserved": "2026-09-11T18:15:01.808Z",
"dateUpdated": "2026-09-17T18:26:58.389Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82761 (GCVE-0-2026-82761)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:09 – Updated: 2026-09-17 18:26
VLAI
EPSS
VEX
Title
Magic link single-use tokens replayable via TOCTOU race in AshAuthentication
Summary
Time-of-check Time-of-use (TOCTOU) Race Condition vulnerability in team-alembic AshAuthentication allows an attacker holding a leaked magic link to replay its single-use token and authenticate as the target subject. A magic link configured with single_use_token?, which is the default, is meant to be redeemable exactly once, but nothing serialises the token's validity check against its consumption, so concurrent redemptions of one token all succeed and each yields a full user token.
Sign-in verifies the JWT with Jwt.verify/4 and revokes it only afterwards: AshAuthentication.Strategy.MagicLink.SignInPreparation revokes in a Query.after_action callback, and AshAuthentication.Strategy.MagicLink.SignInChange in an after_transaction hook that runs once the sign-in has already committed. AshAuthentication.TokenResource.Actions.revoke/3 writes the revocation as an upsert, so a concurrent duplicate revocation silently succeeds instead of conflicting and no request ever loses the race.
This issue affects ash_authentication: from 3.9.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:25 UTC
CWE
- CWE-367 - Time-of-check Time-of-use (TOCTOU) Race Condition
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
3.9.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
cf3d227ef25912cf1b0c5fa80f20001f5c46a102 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82761",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:25:13.930894Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:26:08.563Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInChange\u0027",
"\u0027Elixir.AshAuthentication.TokenResource.Actions\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/magic_link/sign_in_preparation.ex",
"lib/ash_authentication/strategies/magic_link/sign_in_change.ex",
"lib/ash_authentication/token_resource/actions.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInChange\u0027:change/3"
},
{
"name": "\u0027Elixir.AshAuthentication.TokenResource.Actions\u0027:revoke/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "3.9.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInPreparation\u0027",
"\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInChange\u0027",
"\u0027Elixir.AshAuthentication.TokenResource.Actions\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/strategies/magic_link/sign_in_preparation.ex",
"lib/ash_authentication/strategies/magic_link/sign_in_change.ex",
"lib/ash_authentication/token_resource/actions.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInPreparation\u0027:prepare/3"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.MagicLink.SignInChange\u0027:change/3"
},
{
"name": "\u0027Elixir.AshAuthentication.TokenResource.Actions\u0027:revoke/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "18dfdb36c14aa6a61df8572bce2d5ec36b1d9840",
"status": "unaffected"
},
{
"at": "9ef6864b8833d3b795427a7b8dc518a4997d41ab",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "cf3d227ef25912cf1b0c5fa80f20001f5c46a102",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "3.9.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-11T18:05:13.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eTime-of-check Time-of-use (TOCTOU) Race Condition vulnerability in team-alembic AshAuthentication allows an attacker holding a leaked magic link to replay its single-use token and authenticate as the target subject. A magic link configured with \u003ccode\u003esingle_use_token?\u003c/code\u003e, which is the default, is meant to be redeemable exactly once, but nothing serialises the token\u0027s validity check against its consumption, so concurrent redemptions of one token all succeed and each yields a full user token.\u003c/p\u003e\n\u003cp\u003eSign-in verifies the JWT with \u003ccode\u003eJwt.verify/4\u003c/code\u003e and revokes it only afterwards: \u003ccode\u003eAshAuthentication.Strategy.MagicLink.SignInPreparation\u003c/code\u003e revokes in a \u003ccode\u003eQuery.after_action\u003c/code\u003e callback, and \u003ccode\u003eAshAuthentication.Strategy.MagicLink.SignInChange\u003c/code\u003e in an \u003ccode\u003eafter_transaction\u003c/code\u003e hook that runs once the sign-in has already committed. \u003ccode\u003eAshAuthentication.TokenResource.Actions.revoke/3\u003c/code\u003e writes the revocation as an upsert, so a concurrent duplicate revocation silently succeeds instead of conflicting and no request ever loses the race.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 3.9.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Time-of-check Time-of-use (TOCTOU) Race Condition vulnerability in team-alembic AshAuthentication allows an attacker holding a leaked magic link to replay its single-use token and authenticate as the target subject. A magic link configured with `single_use_token?`, which is the default, is meant to be redeemable exactly once, but nothing serialises the token\u0027s validity check against its consumption, so concurrent redemptions of one token all succeed and each yields a full user token.\n\nSign-in verifies the JWT with `Jwt.verify/4` and revokes it only afterwards: `AshAuthentication.Strategy.MagicLink.SignInPreparation` revokes in a `Query.after_action` callback, and `AshAuthentication.Strategy.MagicLink.SignInChange` in an `after_transaction` hook that runs once the sign-in has already committed. `AshAuthentication.TokenResource.Actions.revoke/3` writes the revocation as an upsert, so a concurrent duplicate revocation silently succeeds instead of conflicting and no request ever loses the race.\n\nThis issue affects ash_authentication: from 3.9.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Time-of-check Time-of-use (TOCTOU) Race Condition vulnerability in team-alembic AshAuthentication allows an attacker holding a leaked magic link to replay its single-use token and authenticate as the target subject. A magic link configured with single_use_token?, which is the default, is meant to be redeemable exactly once, but nothing serialises the token\u0027s validity check against its consumption, so concurrent redemptions of one token all succeed and each yields a full user token.\n\nSign-in verifies the JWT with Jwt.verify/4 and revokes it only afterwards: AshAuthentication.Strategy.MagicLink.SignInPreparation revokes in a Query.after_action callback, and AshAuthentication.Strategy.MagicLink.SignInChange in an after_transaction hook that runs once the sign-in has already committed. AshAuthentication.TokenResource.Actions.revoke/3 writes the revocation as an upsert, so a concurrent duplicate revocation silently succeeds instead of conflicting and no request ever loses the race.\n\nThis issue affects ash_authentication: from 3.9.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-29",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-29 Leveraging Time-of-Check and Time-of-Use (TOCTOU) Race Conditions"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-367",
"description": "CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:09:01.534Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-23gr-vcp4-r27q"
},
{
"name": "EEF CNA record for CVE-2026-82761",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82761.html"
},
{
"name": "OSV record EEF-CVE-2026-82761",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82761"
},
{
"name": "Introducing commit cf3d227 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/cf3d227ef25912cf1b0c5fa80f20001f5c46a102"
},
{
"name": "Fix commit 18dfdb3 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/18dfdb36c14aa6a61df8572bce2d5ec36b1d9840"
},
{
"name": "Fix commit 9ef6864 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/9ef6864b8833d3b795427a7b8dc518a4997d41ab"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Magic link single-use tokens replayable via TOCTOU race in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82761",
"datePublished": "2026-09-17T13:09:01.534Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-17T18:26:08.563Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82685 (GCVE-0-2026-82685)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:08 – Updated: 2026-09-17 18:23
VLAI
EPSS
VEX
Title
Confirmation token accepted on any record in AshAuthentication
Summary
Authorization Bypass Through User-Controlled Key vulnerability in team-alembic AshAuthentication allows an authenticated attacker to overwrite and confirm another user's email address, and so take over that account. A confirmation token issued to one user is accepted on any other user's record.
AshAuthentication.AddOn.Confirmation.ConfirmChange verifies the token's signature and its act claim, then applies the changes stored against that token to whichever record the changeset targets, never comparing the sub claim against changeset.data. An attacker who registers an account and changes their own email replays the resulting token against a victim's record id, writing in their own address with force_change_attributes/2 and stamping confirmed_at, after which an ordinary password reset yields the account. The library's own confirmation flow is unaffected, because AshAuthentication.AddOn.Confirmation.Actions.confirm/3 resolves sub to a user and targets that record.
This issue affects ash_authentication: from 0.5.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:23 UTC
CWE
- CWE-639 - Authorization Bypass Through User-Controlled Key
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
0.5.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
1d4bb00617aecae85c33f2ff5bc7e094c6449a6e , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82685",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:23:08.889793Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:23:51.075Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.Confirmation.ConfirmChange\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/confirmation/confirm_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.Confirmation.ConfirmChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "0.5.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.Confirmation.ConfirmChange\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/confirmation/confirm_change.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.Confirmation.ConfirmChange\u0027:change/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "d7c15c21d39c009206e010cd67e2d86370fe7a28",
"status": "unaffected"
},
{
"at": "2a2396af131ab67e2f445b805fecce8e6ca86c0e",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "1d4bb00617aecae85c33f2ff5bc7e094c6449a6e",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "0.5.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-11T17:35:42.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAuthorization Bypass Through User-Controlled Key vulnerability in team-alembic AshAuthentication allows an authenticated attacker to overwrite and confirm another user\u0027s email address, and so take over that account. A confirmation token issued to one user is accepted on any other user\u0027s record.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.AddOn.Confirmation.ConfirmChange\u003c/code\u003e verifies the token\u0027s signature and its \u003ccode\u003eact\u003c/code\u003e claim, then applies the changes stored against that token to whichever record the changeset targets, never comparing the \u003ccode\u003esub\u003c/code\u003e claim against \u003ccode\u003echangeset.data\u003c/code\u003e. An attacker who registers an account and changes their own email replays the resulting token against a victim\u0027s record id, writing in their own address with \u003ccode\u003eforce_change_attributes/2\u003c/code\u003e and stamping \u003ccode\u003econfirmed_at\u003c/code\u003e, after which an ordinary password reset yields the account. The library\u0027s own confirmation flow is unaffected, because \u003ccode\u003eAshAuthentication.AddOn.Confirmation.Actions.confirm/3\u003c/code\u003e resolves \u003ccode\u003esub\u003c/code\u003e to a user and targets that record.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 0.5.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Authorization Bypass Through User-Controlled Key vulnerability in team-alembic AshAuthentication allows an authenticated attacker to overwrite and confirm another user\u0027s email address, and so take over that account. A confirmation token issued to one user is accepted on any other user\u0027s record.\n\n`AshAuthentication.AddOn.Confirmation.ConfirmChange` verifies the token\u0027s signature and its `act` claim, then applies the changes stored against that token to whichever record the changeset targets, never comparing the `sub` claim against `changeset.data`. An attacker who registers an account and changes their own email replays the resulting token against a victim\u0027s record id, writing in their own address with `force_change_attributes/2` and stamping `confirmed_at`, after which an ordinary password reset yields the account. The library\u0027s own confirmation flow is unaffected, because `AshAuthentication.AddOn.Confirmation.Actions.confirm/3` resolves `sub` to a user and targets that record.\n\nThis issue affects ash_authentication: from 0.5.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Authorization Bypass Through User-Controlled Key vulnerability in team-alembic AshAuthentication allows an authenticated attacker to overwrite and confirm another user\u0027s email address, and so take over that account. A confirmation token issued to one user is accepted on any other user\u0027s record.\n\nAshAuthentication.AddOn.Confirmation.ConfirmChange verifies the token\u0027s signature and its act claim, then applies the changes stored against that token to whichever record the changeset targets, never comparing the sub claim against changeset.data. An attacker who registers an account and changes their own email replays the resulting token against a victim\u0027s record id, writing in their own address with force_change_attributes/2 and stamping confirmed_at, after which an ordinary password reset yields the account. The library\u0027s own confirmation flow is unaffected, because AshAuthentication.AddOn.Confirmation.Actions.confirm/3 resolves sub to a user and targets that record.\n\nThis issue affects ash_authentication: from 0.5.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-21",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-21 Exploitation of Trusted Identifiers"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 7.6,
"baseSeverity": "HIGH",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-639",
"description": "CWE-639 Authorization Bypass Through User-Controlled Key",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:08:56.491Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-g636-26vf-2w63"
},
{
"name": "EEF CNA record for CVE-2026-82685",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82685.html"
},
{
"name": "OSV record EEF-CVE-2026-82685",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82685"
},
{
"name": "Introducing commit 1d4bb00 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/1d4bb00617aecae85c33f2ff5bc7e094c6449a6e"
},
{
"name": "Fix commit d7c15c2 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/d7c15c21d39c009206e010cd67e2d86370fe7a28"
},
{
"name": "Fix commit 2a2396a in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/2a2396af131ab67e2f445b805fecce8e6ca86c0e"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Confirmation token accepted on any record in AshAuthentication"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82685",
"datePublished": "2026-09-17T13:08:56.491Z",
"dateReserved": "2026-08-31T00:45:02.436Z",
"dateUpdated": "2026-09-17T18:23:51.075Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82760 (GCVE-0-2026-82760)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:08 – Updated: 2026-09-17 18:21
VLAI
EPSS
VEX
Title
Superlinear base62 decoding exhausts CPU and memory in AshAuthentication API key sign-in
Summary
Inefficient Algorithmic Complexity vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to exhaust CPU and memory via an oversized base62 segment in a submitted API key.
AshAuthentication.Base.decode62/1 in lib/ash_authentication/base.ex splits its argument into one binary per character and folds it with charval62/2, which recomputes Integer.pow(62, index) at every position instead of accumulating by Horner's method, so cost grows roughly cubically in the input length. bindecode62/1 in the same module is quadratic through Integer.undigits/2 and Integer.digits/2. Neither function caps byte_size/1, and AshAuthentication.Strategy.ApiKey.SignInPreparation passes the underscore-separated segments of the submitted key straight into both, before any key lookup and without prior authentication. The surrounding rescue clauses catch exceptions, not CPU or memory exhaustion.
This issue affects ash_authentication: from 4.8.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:21 UTC
CWE
- CWE-407 - Inefficient Algorithmic Complexity
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.8.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
f3a53f480088419788d5c3934af3131fa9066773 , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82760",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:21:05.949151Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:21:26.238Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Base\u0027",
"\u0027Elixir.AshAuthentication.Strategy.ApiKey.SignInPreparation\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/base.ex",
"lib/ash_authentication/strategies/api_key/sign_in_preparation.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Base\u0027:decode62/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Base\u0027:bindecode62/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.ApiKey.SignInPreparation\u0027:prepare/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.8.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Base\u0027",
"\u0027Elixir.AshAuthentication.Strategy.ApiKey.SignInPreparation\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/base.ex",
"lib/ash_authentication/strategies/api_key/sign_in_preparation.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Base\u0027:decode62/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Base\u0027:bindecode62/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Strategy.ApiKey.SignInPreparation\u0027:prepare/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "d5a5d4cb5cc17fbd6e2a120a6111b47accad4b8e",
"status": "unaffected"
},
{
"at": "dfb19c897853686ab481c5e773f7a1a0c74dea04",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "f3a53f480088419788d5c3934af3131fa9066773",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.8.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-11T17:59:54.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eInefficient Algorithmic Complexity vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to exhaust CPU and memory via an oversized base62 segment in a submitted API key.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.Base.decode62/1\u003c/code\u003e in \u003ccode\u003elib/ash_authentication/base.ex\u003c/code\u003e splits its argument into one binary per character and folds it with \u003ccode\u003echarval62/2\u003c/code\u003e, which recomputes \u003ccode\u003eInteger.pow(62, index)\u003c/code\u003e at every position instead of accumulating by Horner\u0027s method, so cost grows roughly cubically in the input length. \u003ccode\u003ebindecode62/1\u003c/code\u003e in the same module is quadratic through \u003ccode\u003eInteger.undigits/2\u003c/code\u003e and \u003ccode\u003eInteger.digits/2\u003c/code\u003e. Neither function caps \u003ccode\u003ebyte_size/1\u003c/code\u003e, and \u003ccode\u003eAshAuthentication.Strategy.ApiKey.SignInPreparation\u003c/code\u003e passes the underscore-separated segments of the submitted key straight into both, before any key lookup and without prior authentication. The surrounding \u003ccode\u003erescue\u003c/code\u003e clauses catch exceptions, not CPU or memory exhaustion.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.8.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Inefficient Algorithmic Complexity vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to exhaust CPU and memory via an oversized base62 segment in a submitted API key.\n\n`AshAuthentication.Base.decode62/1` in `lib/ash_authentication/base.ex` splits its argument into one binary per character and folds it with `charval62/2`, which recomputes `Integer.pow(62, index)` at every position instead of accumulating by Horner\u0027s method, so cost grows roughly cubically in the input length. `bindecode62/1` in the same module is quadratic through `Integer.undigits/2` and `Integer.digits/2`. Neither function caps `byte_size/1`, and `AshAuthentication.Strategy.ApiKey.SignInPreparation` passes the underscore-separated segments of the submitted key straight into both, before any key lookup and without prior authentication. The surrounding `rescue` clauses catch exceptions, not CPU or memory exhaustion.\n\nThis issue affects ash_authentication: from 4.8.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Inefficient Algorithmic Complexity vulnerability in team-alembic AshAuthentication allows an unauthenticated attacker to exhaust CPU and memory via an oversized base62 segment in a submitted API key.\n\nAshAuthentication.Base.decode62/1 in lib/ash_authentication/base.ex splits its argument into one binary per character and folds it with charval62/2, which recomputes Integer.pow(62, index) at every position instead of accumulating by Horner\u0027s method, so cost grows roughly cubically in the input length. bindecode62/1 in the same module is quadratic through Integer.undigits/2 and Integer.digits/2. Neither function caps byte_size/1, and AshAuthentication.Strategy.ApiKey.SignInPreparation passes the underscore-separated segments of the submitted key straight into both, before any key lookup and without prior authentication. The surrounding rescue clauses catch exceptions, not CPU or memory exhaustion.\n\nThis issue affects ash_authentication: from 4.8.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-407",
"description": "CWE-407 Inefficient Algorithmic Complexity",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:08:46.382Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-q876-xr24-2mcx"
},
{
"name": "EEF CNA record for CVE-2026-82760",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82760.html"
},
{
"name": "OSV record EEF-CVE-2026-82760",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82760"
},
{
"name": "Introducing commit f3a53f4 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/f3a53f480088419788d5c3934af3131fa9066773"
},
{
"name": "Fix commit d5a5d4c in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/d5a5d4cb5cc17fbd6e2a120a6111b47accad4b8e"
},
{
"name": "Fix commit dfb19c8 in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/dfb19c897853686ab481c5e773f7a1a0c74dea04"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Superlinear base62 decoding exhausts CPU and memory in AshAuthentication API key sign-in"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82760",
"datePublished": "2026-09-17T13:08:46.382Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-17T18:21:26.238Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82759 (GCVE-0-2026-82759)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:08 – Updated: 2026-09-17 18:19
VLAI
EPSS
VEX
Title
Reversible IP address pseudonymisation in AshAuthentication audit log hash mode
Summary
Use of a One-Way Hash with a Predictable Salt vulnerability in team-alembic AshAuthentication allows readers of the audit store to recover the client IP addresses that the audit log add-on's :hash privacy mode is meant to pseudonymise.
AshAuthentication.AddOn.AuditLog.IpPrivacy.hash_ip/1 computes a single unkeyed :crypto.hash(:sha256, salt <> ip) and truncates the result to 16 hexadecimal characters. The salt is read from the :audit_log_ip_salt or :secret application config keys, and falls back to the constant "default-salt-change-in-production" published in the library source when neither is set, with nothing warning that the default is in use. The IPv4 space is only 2^32 values and SHA-256 is fast, so the whole hash table is precomputable and every stored value maps back to its source address. Truncating to 16 characters does not help, and even a configured salt leaves the hash cheap enough to enumerate once it leaks.
This issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:19 UTC
CWE
- CWE-760 - Use of a One-Way Hash with a Predictable Salt
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.12.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.14 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
255cfc9c0e511b7e0de39f8b3d676ae994fae06c , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82759",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:19:03.885925Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:19:18.209Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/audit_log/ip_privacy.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027:hash_ip/1"
},
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027:apply_privacy/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.12.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.14",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/audit_log/ip_privacy.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027:hash_ip/1"
},
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.IpPrivacy\u0027:apply_privacy/3"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "d8a9c4b6bde828fdc8346198d5e4f588b5937541",
"status": "unaffected"
},
{
"at": "c3a6d5fe0d4fd383ea81b0402db0a96638479478",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "255cfc9c0e511b7e0de39f8b3d676ae994fae06c",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eOnly applications that enable the \u003ccode\u003eaudit_log\u003c/code\u003e add-on and set its \u003ccode\u003eip_privacy\u003c/code\u003e mode to \u003ccode\u003e:hash\u003c/code\u003e store the affected value. Other modes (\u003ccode\u003e:none\u003c/code\u003e, \u003ccode\u003e:truncate\u003c/code\u003e, \u003ccode\u003e:exclude\u003c/code\u003e) do not reach \u003ccode\u003ehash_ip/1\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe complete break additionally requires the default salt, that is neither \u003ccode\u003e:audit_log_ip_salt\u003c/code\u003e nor \u003ccode\u003e:secret\u003c/code\u003e configured under the \u003ccode\u003e:ash_authentication\u003c/code\u003e application. This is the out-of-the-box state: no warning or error is raised when the hardcoded salt is in use.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Only applications that enable the `audit_log` add-on and set its `ip_privacy` mode to `:hash` store the affected value. Other modes (`:none`, `:truncate`, `:exclude`) do not reach `hash_ip/1`.\n\nThe complete break additionally requires the default salt, that is neither `:audit_log_ip_salt` nor `:secret` configured under the `:ash_authentication` application. This is the out-of-the-box state: no warning or error is raised when the hardcoded salt is in use."
}
],
"value": "Only applications that enable the audit_log add-on and set its ip_privacy mode to :hash store the affected value. Other modes (:none, :truncate, :exclude) do not reach hash_ip/1.\n\nThe complete break additionally requires the default salt, that is neither :audit_log_ip_salt nor :secret configured under the :ash_authentication application. This is the out-of-the-box state: no warning or error is raised when the hardcoded salt is in use."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.12.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.14",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
}
],
"dateAssigned": "2026-09-11T17:53:27.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUse of a One-Way Hash with a Predictable Salt vulnerability in team-alembic AshAuthentication allows readers of the audit store to recover the client IP addresses that the audit log add-on\u0027s \u003ccode\u003e:hash\u003c/code\u003e privacy mode is meant to pseudonymise.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshAuthentication.AddOn.AuditLog.IpPrivacy.hash_ip/1\u003c/code\u003e computes a single unkeyed \u003ccode\u003e:crypto.hash(:sha256, salt \u0026lt;\u0026gt; ip)\u003c/code\u003e and truncates the result to 16 hexadecimal characters. The salt is read from the \u003ccode\u003e:audit_log_ip_salt\u003c/code\u003e or \u003ccode\u003e:secret\u003c/code\u003e application config keys, and falls back to the constant \u003ccode\u003e\"default-salt-change-in-production\"\u003c/code\u003e published in the library source when neither is set, with nothing warning that the default is in use. The IPv4 space is only 2^32 values and SHA-256 is fast, so the whole hash table is precomputable and every stored value maps back to its source address. Truncating to 16 characters does not help, and even a configured salt leaves the hash cheap enough to enumerate once it leaks.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Use of a One-Way Hash with a Predictable Salt vulnerability in team-alembic AshAuthentication allows readers of the audit store to recover the client IP addresses that the audit log add-on\u0027s `:hash` privacy mode is meant to pseudonymise.\n\n`AshAuthentication.AddOn.AuditLog.IpPrivacy.hash_ip/1` computes a single unkeyed `:crypto.hash(:sha256, salt \u003c\u003e ip)` and truncates the result to 16 hexadecimal characters. The salt is read from the `:audit_log_ip_salt` or `:secret` application config keys, and falls back to the constant `\"default-salt-change-in-production\"` published in the library source when neither is set, with nothing warning that the default is in use. The IPv4 space is only 2^32 values and SHA-256 is fast, so the whole hash table is precomputable and every stored value maps back to its source address. Truncating to 16 characters does not help, and even a configured salt leaves the hash cheap enough to enumerate once it leaks.\n\nThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"value": "Use of a One-Way Hash with a Predictable Salt vulnerability in team-alembic AshAuthentication allows readers of the audit store to recover the client IP addresses that the audit log add-on\u0027s :hash privacy mode is meant to pseudonymise.\n\nAshAuthentication.AddOn.AuditLog.IpPrivacy.hash_ip/1 computes a single unkeyed :crypto.hash(:sha256, salt \u003c\u003e ip) and truncates the result to 16 hexadecimal characters. The salt is read from the :audit_log_ip_salt or :secret application config keys, and falls back to the constant \"default-salt-change-in-production\" published in the library source when neither is set, with nothing warning that the default is in use. The IPv4 space is only 2^32 values and SHA-256 is fast, so the whole hash table is precomputable and every stored value maps back to its source address. Truncating to 16 characters does not help, and even a configured salt leaves the hash cheap enough to enumerate once it leaks.\n\nThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.14."
}
],
"impacts": [
{
"capecId": "CAPEC-112",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-112 Brute Force"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 1.8,
"baseSeverity": "LOW",
"privilegesRequired": "HIGH",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:H/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-760",
"description": "CWE-760 Use of a One-Way Hash with a Predictable Salt",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:08:21.929Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-cgqj-pcpq-xhfm"
},
{
"name": "EEF CNA record for CVE-2026-82759",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82759.html"
},
{
"name": "OSV record EEF-CVE-2026-82759",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82759"
},
{
"name": "Introducing commit 255cfc9 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/255cfc9c0e511b7e0de39f8b3d676ae994fae06c"
},
{
"name": "Fix commit d8a9c4b in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/d8a9c4b6bde828fdc8346198d5e4f588b5937541"
},
{
"name": "Fix commit c3a6d5f in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/c3a6d5fe0d4fd383ea81b0402db0a96638479478"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Reversible IP address pseudonymisation in AshAuthentication audit log hash mode"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82759",
"datePublished": "2026-09-17T13:08:21.929Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-17T18:19:18.209Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82723 (GCVE-0-2026-82723)
Vulnerability from cvelistv5 – Published: 2026-09-17 13:08 – Updated: 2026-09-17 18:18
VLAI
EPSS
VEX
Title
Actor record with password digest stored in AshAuthentication audit log entries
Summary
Insertion of Sensitive Information into Log File vulnerability in team-alembic AshAuthentication allows disclosure of user password digests to readers of the audit store.
The audit_log add-on builds each entry's extra_data in AshAuthentication.AddOn.AuditLog.Auditor.build_extra_data/4, which takes :actor from the action callback context verbatim. Any audited action invoked with actor: set to a user record therefore deposits that record, including its hashed_password attribute, into the audit entry. The same module already collapses the audited identity to an opaque string via AshAuthentication.user_to_subject/1 and filters params against the strategy's configured allow-list, so the actor is the only stored value that reaches the audit store unfiltered. Marking the attribute sensitive?: true does not help, because that redacts inspect/1 output rather than JSON encoding or raw-term storage.
There is no attacker-controlled trigger and no network disclosure path: entries accumulate from ordinary authenticated activity, and an attacker's own requests deposit only their own digest. Exploitation requires independent read access to the audit store, such as database credentials, an audit role, a backup, or a log shipper, at which point the digests support offline password attack against every active account. Whether the material persists depends on the data layer, since raw-term stores keep it verbatim while a SQL store raises Protocol.UndefinedError and drops the entry unless the user resource derives Jason.Encoder.
This issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.2.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-17 18:18 UTC
CWE
- CWE-532 - Insertion of Sensitive Information into Log File
Assigner
References
6 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| team-alembic | ash_authentication |
Affected:
4.12.0 , < 4.15.0
(semver)
Affected: 5.0.0-rc.0 , < 5.0.0-rc.2 (semver) cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
|
| team-alembic | ash_authentication |
Affected:
255cfc9c0e511b7e0de39f8b3d676ae994fae06c , < *
(git)
cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82723",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-17T18:18:14.370339Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T18:18:28.208Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.AuditLog.Auditor\u0027"
],
"packageName": "ash_authentication",
"packageURL": "pkg:hex/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/audit_log/auditor.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.Auditor\u0027:build_extra_data/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"lessThan": "4.15.0",
"status": "affected",
"version": "4.12.0",
"versionType": "semver"
},
{
"lessThan": "5.0.0-rc.2",
"status": "affected",
"version": "5.0.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.AddOn.AuditLog.Auditor\u0027"
],
"packageName": "team-alembic/ash_authentication",
"packageURL": "pkg:github/team-alembic/ash_authentication",
"product": "ash_authentication",
"programFiles": [
"lib/ash_authentication/add_ons/audit_log/auditor.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.AddOn.AuditLog.Auditor\u0027:build_extra_data/4"
}
],
"repo": "https://github.com/team-alembic/ash_authentication",
"vendor": "team-alembic",
"versions": [
{
"changes": [
{
"at": "17ea0dff3bad56a7e915e050c43ab7160b37901f",
"status": "unaffected"
},
{
"at": "f6b49cc98b9ff7c16a1aeb12e35633a8d93a211f",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "255cfc9c0e511b7e0de39f8b3d676ae994fae06c",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "4.15.0",
"versionStartIncluding": "4.12.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:team-alembic:ash_authentication:*:*:*:*:*:*:*:*",
"versionEndExcluding": "5.0.0-rc.2",
"versionStartIncluding": "5.0.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "James Harton"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eInsertion of Sensitive Information into Log File vulnerability in team-alembic AshAuthentication allows disclosure of user password digests to readers of the audit store.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003eaudit_log\u003c/code\u003e add-on builds each entry\u0027s \u003ccode\u003eextra_data\u003c/code\u003e in \u003ccode\u003eAshAuthentication.AddOn.AuditLog.Auditor.build_extra_data/4\u003c/code\u003e, which takes \u003ccode\u003e:actor\u003c/code\u003e from the action callback context verbatim. Any audited action invoked with \u003ccode\u003eactor:\u003c/code\u003e set to a user record therefore deposits that record, including its \u003ccode\u003ehashed_password\u003c/code\u003e attribute, into the audit entry. The same module already collapses the audited identity to an opaque string via \u003ccode\u003eAshAuthentication.user_to_subject/1\u003c/code\u003e and filters \u003ccode\u003eparams\u003c/code\u003e against the strategy\u0027s configured allow-list, so the actor is the only stored value that reaches the audit store unfiltered. Marking the attribute \u003ccode\u003esensitive?: true\u003c/code\u003e does not help, because that redacts \u003ccode\u003einspect/1\u003c/code\u003e output rather than JSON encoding or raw-term storage.\u003c/p\u003e\n\u003cp\u003eThere is no attacker-controlled trigger and no network disclosure path: entries accumulate from ordinary authenticated activity, and an attacker\u0027s own requests deposit only their own digest. Exploitation requires independent read access to the audit store, such as database credentials, an audit role, a backup, or a log shipper, at which point the digests support offline password attack against every active account. Whether the material persists depends on the data layer, since raw-term stores keep it verbatim while a SQL store raises \u003ccode\u003eProtocol.UndefinedError\u003c/code\u003e and drops the entry unless the user resource derives \u003ccode\u003eJason.Encoder\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Insertion of Sensitive Information into Log File vulnerability in team-alembic AshAuthentication allows disclosure of user password digests to readers of the audit store.\n\nThe `audit_log` add-on builds each entry\u0027s `extra_data` in `AshAuthentication.AddOn.AuditLog.Auditor.build_extra_data/4`, which takes `:actor` from the action callback context verbatim. Any audited action invoked with `actor:` set to a user record therefore deposits that record, including its `hashed_password` attribute, into the audit entry. The same module already collapses the audited identity to an opaque string via `AshAuthentication.user_to_subject/1` and filters `params` against the strategy\u0027s configured allow-list, so the actor is the only stored value that reaches the audit store unfiltered. Marking the attribute `sensitive?: true` does not help, because that redacts `inspect/1` output rather than JSON encoding or raw-term storage.\n\nThere is no attacker-controlled trigger and no network disclosure path: entries accumulate from ordinary authenticated activity, and an attacker\u0027s own requests deposit only their own digest. Exploitation requires independent read access to the audit store, such as database credentials, an audit role, a backup, or a log shipper, at which point the digests support offline password attack against every active account. Whether the material persists depends on the data layer, since raw-term stores keep it verbatim while a SQL store raises `Protocol.UndefinedError` and drops the entry unless the user resource derives `Jason.Encoder`.\n\nThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.2."
}
],
"value": "Insertion of Sensitive Information into Log File vulnerability in team-alembic AshAuthentication allows disclosure of user password digests to readers of the audit store.\n\nThe audit_log add-on builds each entry\u0027s extra_data in AshAuthentication.AddOn.AuditLog.Auditor.build_extra_data/4, which takes :actor from the action callback context verbatim. Any audited action invoked with actor: set to a user record therefore deposits that record, including its hashed_password attribute, into the audit entry. The same module already collapses the audited identity to an opaque string via AshAuthentication.user_to_subject/1 and filters params against the strategy\u0027s configured allow-list, so the actor is the only stored value that reaches the audit store unfiltered. Marking the attribute sensitive?: true does not help, because that redacts inspect/1 output rather than JSON encoding or raw-term storage.\n\nThere is no attacker-controlled trigger and no network disclosure path: entries accumulate from ordinary authenticated activity, and an attacker\u0027s own requests deposit only their own digest. Exploitation requires independent read access to the audit store, such as database credentials, an audit role, a backup, or a log shipper, at which point the digests support offline password attack against every active account. Whether the material persists depends on the data layer, since raw-term stores keep it verbatim while a SQL store raises Protocol.UndefinedError and drops the entry unless the user resource derives Jason.Encoder.\n\nThis issue affects ash_authentication: from 4.12.0 before 4.15.0 and from 5.0.0-rc.0 before 5.0.0-rc.2."
}
],
"impacts": [
{
"capecId": "CAPEC-49",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-49 Password Brute Forcing"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "HIGH",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 1.8,
"baseSeverity": "LOW",
"privilegesRequired": "HIGH",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:H/AT:P/PR:H/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-532",
"description": "CWE-532 Insertion of Sensitive Information into Log File",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-17T13:08:05.355Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/team-alembic/ash_authentication/security/advisories/GHSA-59wx-q3r8-ghv4"
},
{
"name": "EEF CNA record for CVE-2026-82723",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82723.html"
},
{
"name": "OSV record EEF-CVE-2026-82723",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82723"
},
{
"name": "Introducing commit 255cfc9 in team-alembic/ash_authentication",
"tags": [
"related"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/255cfc9c0e511b7e0de39f8b3d676ae994fae06c"
},
{
"name": "Fix commit 17ea0df in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/17ea0dff3bad56a7e915e050c43ab7160b37901f"
},
{
"name": "Fix commit f6b49cc in team-alembic/ash_authentication",
"tags": [
"patch"
],
"url": "https://github.com/team-alembic/ash_authentication/commit/f6b49cc98b9ff7c16a1aeb12e35633a8d93a211f"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Actor record with password digest stored in AshAuthentication audit log entries"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82723",
"datePublished": "2026-09-17T13:08:05.355Z",
"dateReserved": "2026-08-31T00:59:08.960Z",
"dateUpdated": "2026-09-17T18:18:28.208Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-86338 (GCVE-0-2026-86338)
Vulnerability from cvelistv5 – Published: 2026-09-16 08:28 – Updated: 2026-09-16 14:49
VLAI
EPSS
VEX
Title
Ash field policies do not filter-nil forbidden calculations and aggregates, enabling an information-disclosure oracle
Summary
Ash field_policies are documented to protect against filter-based information disclosure: when a field the actor may not see is referenced in a filter, it is replaced with an expression that evaluates to nil, so a filter cannot be used as a yes/no oracle to read a value the actor cannot see.
This nilling was applied to attributes but not to calculations or aggregates. A user-supplied filter reference to a calculation or aggregate carries an Ash.Query.Calculation / Ash.Query.Aggregate struct, which the authorizer's reference replacement did not match (it only matched the Ash.Resource.* structs), so the filter ran against the real value.
As a result, an actor whose field policies forbid a calculation or aggregate can still filter by it (for example filter(secret_calc == "x") or filter(comment_count == n)) and learn the value from whether rows match — an oracle that recovers field-policy-protected values one probe at a time. Filtering is commonly exposed to lower-privileged actors (for example via AshGraphql or AshJsonApi filter arguments), which is exactly the surface field policies are meant to protect.
The fix routes filter references to calculations and aggregates through the same field-policy nilling as attributes.
This issue affects ash: from 2.11.0-rc.0 before 3.33.4.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-16 14:49 UTC
CWE
- CWE-1220 - Insufficient Granularity of Access Control
Assigner
References
5 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash |
Affected:
2.11.0-rc.0 , < 3.33.4
(semver)
cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:* |
|
| ash-project | ash |
Affected:
0b6d93c7c4637280b46ae66ea1d2eaf013701238 , < b3d4503241f3deacb5ceb955e10a4fa927da0f67
(git)
cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-86338",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-16T14:49:09.195379Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T14:49:17.203Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Ash.Policy.Authorizer\u0027"
],
"packageName": "ash",
"packageURL": "pkg:hex/ash",
"product": "ash",
"programFiles": [
"lib/ash/policy/authorizer/authorizer.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Ash.Policy.Authorizer\u0027:do_replace_ref/2"
}
],
"repo": "https://github.com/ash-project/ash",
"vendor": "ash-project",
"versions": [
{
"lessThan": "3.33.4",
"status": "affected",
"version": "2.11.0-rc.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Ash.Policy.Authorizer\u0027"
],
"packageName": "ash-project/ash",
"packageURL": "pkg:github/ash-project/ash",
"product": "ash",
"programFiles": [
"lib/ash/policy/authorizer/authorizer.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Ash.Policy.Authorizer\u0027:do_replace_ref/2"
}
],
"repo": "https://github.com/ash-project/ash",
"vendor": "ash-project",
"versions": [
{
"lessThan": "b3d4503241f3deacb5ceb955e10a4fa927da0f67",
"status": "affected",
"version": "0b6d93c7c4637280b46ae66ea1d2eaf013701238",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when an application uses \u003ccode\u003eAsh.Policy.Authorizer\u003c/code\u003e field policies to restrict a calculation or aggregate, and exposes filtering on it to an actor who is denied that field (for example an authenticated user filtering through AshGraphql or AshJsonApi).\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when an application uses `Ash.Policy.Authorizer` field policies to restrict a calculation or aggregate, and exposes filtering on it to an actor who is denied that field (for example an authenticated user filtering through AshGraphql or AshJsonApi)."
}
],
"value": "Reachable only when an application uses Ash.Policy.Authorizer field policies to restrict a calculation or aggregate, and exposes filtering on it to an actor who is denied that field (for example an authenticated user filtering through AshGraphql or AshJsonApi)."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.33.4",
"versionStartIncluding": "2.11.0-rc.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Jesse Williams"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Jesse Williams"
}
],
"dateAssigned": "2026-09-15T23:33:34.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAsh \u003ccode\u003efield_policies\u003c/code\u003e are documented to protect against filter-based information disclosure: when a field the actor may not see is referenced in a filter, it is replaced with an expression that evaluates to \u003ccode\u003enil\u003c/code\u003e, so a filter cannot be used as a yes/no oracle to read a value the actor cannot see.\u003c/p\u003e\n\u003cp\u003eThis nilling was applied to attributes but not to calculations or aggregates. A user-supplied filter reference to a calculation or aggregate carries an \u003ccode\u003eAsh.Query.Calculation\u003c/code\u003e / \u003ccode\u003eAsh.Query.Aggregate\u003c/code\u003e struct, which the authorizer\u0027s reference replacement did not match (it only matched the \u003ccode\u003eAsh.Resource.*\u003c/code\u003e structs), so the filter ran against the real value.\u003c/p\u003e\n\u003cp\u003eAs a result, an actor whose field policies forbid a calculation or aggregate can still filter by it (for example \u003ccode\u003efilter(secret_calc == \"x\")\u003c/code\u003e or \u003ccode\u003efilter(comment_count == n)\u003c/code\u003e) and learn the value from whether rows match \u2014 an oracle that recovers field-policy-protected values one probe at a time. Filtering is commonly exposed to lower-privileged actors (for example via AshGraphql or AshJsonApi filter arguments), which is exactly the surface field policies are meant to protect.\u003c/p\u003e\n\u003cp\u003eThe fix routes filter references to calculations and aggregates through the same field-policy nilling as attributes.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash: from 2.11.0-rc.0 before 3.33.4.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Ash `field_policies` are documented to protect against filter-based information disclosure: when a field the actor may not see is referenced in a filter, it is replaced with an expression that evaluates to `nil`, so a filter cannot be used as a yes/no oracle to read a value the actor cannot see.\n\nThis nilling was applied to attributes but not to calculations or aggregates. A user-supplied filter reference to a calculation or aggregate carries an `Ash.Query.Calculation` / `Ash.Query.Aggregate` struct, which the authorizer\u0027s reference replacement did not match (it only matched the `Ash.Resource.*` structs), so the filter ran against the real value.\n\nAs a result, an actor whose field policies forbid a calculation or aggregate can still filter by it (for example `filter(secret_calc == \"x\")` or `filter(comment_count == n)`) and learn the value from whether rows match \u2014 an oracle that recovers field-policy-protected values one probe at a time. Filtering is commonly exposed to lower-privileged actors (for example via AshGraphql or AshJsonApi filter arguments), which is exactly the surface field policies are meant to protect.\n\nThe fix routes filter references to calculations and aggregates through the same field-policy nilling as attributes.\n\nThis issue affects ash: from 2.11.0-rc.0 before 3.33.4."
}
],
"value": "Ash field_policies are documented to protect against filter-based information disclosure: when a field the actor may not see is referenced in a filter, it is replaced with an expression that evaluates to nil, so a filter cannot be used as a yes/no oracle to read a value the actor cannot see.\n\nThis nilling was applied to attributes but not to calculations or aggregates. A user-supplied filter reference to a calculation or aggregate carries an Ash.Query.Calculation / Ash.Query.Aggregate struct, which the authorizer\u0027s reference replacement did not match (it only matched the Ash.Resource.* structs), so the filter ran against the real value.\n\nAs a result, an actor whose field policies forbid a calculation or aggregate can still filter by it (for example filter(secret_calc == \"x\") or filter(comment_count == n)) and learn the value from whether rows match \u2014 an oracle that recovers field-policy-protected values one probe at a time. Filtering is commonly exposed to lower-privileged actors (for example via AshGraphql or AshJsonApi filter arguments), which is exactly the surface field policies are meant to protect.\n\nThe fix routes filter references to calculations and aggregates through the same field-policy nilling as attributes.\n\nThis issue affects ash: from 2.11.0-rc.0 before 3.33.4."
}
],
"impacts": [
{
"capecId": "CAPEC-1",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6,
"baseSeverity": "MEDIUM",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1220",
"description": "CWE-1220 Insufficient Granularity of Access Control",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T08:28:44.114Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GHSA-7qr8-wrvq-566q",
"tags": [
"vendor-advisory"
],
"url": "https://github.com/ash-project/ash/security/advisories/GHSA-7qr8-wrvq-566q"
},
{
"name": "EEF CNA record for CVE-2026-86338",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-86338.html"
},
{
"name": "OSV record EEF-CVE-2026-86338",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-86338"
},
{
"name": "Introducing commit 0b6d93c in ash-project/ash",
"tags": [
"related"
],
"url": "https://github.com/ash-project/ash/commit/0b6d93c7c4637280b46ae66ea1d2eaf013701238"
},
{
"name": "Fix commit b3d4503 in ash-project/ash",
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash/commit/b3d4503241f3deacb5ceb955e10a4fa927da0f67"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Ash field policies do not filter-nil forbidden calculations and aggregates, enabling an information-disclosure oracle"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-86338",
"datePublished": "2026-09-16T08:28:44.114Z",
"dateReserved": "2026-09-15T15:30:01.895Z",
"dateUpdated": "2026-09-16T14:49:17.203Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-88255 (GCVE-0-2026-88255)
Vulnerability from cvelistv5 – Published: 2026-09-16 08:24 – Updated: 2026-09-16 14:49
VLAI
EPSS
VEX
Title
mpp Tempo keys its pre-broadcast dedup reserve on the caller-supplied transaction encoding, so a re-encoded signed transaction reserves a second slot
Summary
Improper Validation of Unsafe Equivalence in Input in ZenHive mpp allows an unauthenticated remote client to pass the Tempo duplicate-submission gate twice with one signed transaction.
MPP.Methods.Tempo reserves the pre-broadcast dedup slot on the caller-supplied hex in reserve_hash_atomic/2, keyed through store_key/1 on tx.raw rather than on a canonical form of the transaction. The deserializer stores the caller's hex verbatim and accepts both recovery-id encodings, so one signed transaction submitted once with v=27 and once with v=0 yields two distinct reserve keys, and both pass the reserve and reach the broadcast path. The plug-level credential replay store is deliberately carved out for tempo in lib/mpp/replay.ex, leaving this reserve as the only gate, and the post-broadcast mark writes the canonical hash key that the raw-keyed reserve never reads.
What the duplicate submission yields depends on the node: a nonce-reuse rejection fails closed, while a node that answers with the canonical hash for an already-known transaction returns a second valid Payment-Receipt for a single on-chain payment.
This issue affects mpp: from 0.2.0 before 0.16.2.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-16 14:49 UTC
CWE
- CWE-1289 - Improper Validation of Unsafe Equivalence in Input
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/ZenHive/mpp/security/advisorie… | relatedvendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-88255.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-88255 | related |
| https://github.com/ZenHive/mpp/commit/f8904666061… | related |
| https://github.com/ZenHive/mpp/commit/e12bd4a1cea… | patch |
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-88255",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-16T14:49:50.266563Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T14:49:57.782Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.MPP.Methods.Tempo\u0027"
],
"packageName": "mpp",
"packageURL": "pkg:hex/mpp",
"product": "mpp",
"programFiles": [
"lib/mpp/methods/tempo.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.MPP.Methods.Tempo\u0027:verify/2"
}
],
"repo": "https://github.com/ZenHive/mpp",
"vendor": "ZenHive",
"versions": [
{
"lessThan": "0.16.2",
"status": "affected",
"version": "0.2.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.MPP.Methods.Tempo\u0027"
],
"packageName": "zenhive/mpp",
"packageURL": "pkg:github/zenhive/mpp",
"product": "mpp",
"programFiles": [
"lib/mpp/methods/tempo.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.MPP.Methods.Tempo\u0027:verify/2"
}
],
"repo": "https://github.com/ZenHive/mpp",
"vendor": "ZenHive",
"versions": [
{
"lessThan": "e12bd4a1cea2e97c2a01fc059c48e5594a7b4a43",
"status": "affected",
"version": "f8904666061fbab695874856d8fcd02c471dfe1b",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable when \u003ccode\u003eMPP.Methods.Tempo\u003c/code\u003e broadcasts a \u003ccode\u003etype=\"transaction\"\u003c/code\u003e credential with a dedup store in place. From mpp 0.7.0 the dedup store is on by default (the app-started \u003ccode\u003eMPP.Tempo.ConCacheStore\u003c/code\u003e; opt out with \u003ccode\u003estore: false\u003c/code\u003e), so every default Tempo deployment from 0.7.0 before 0.16.2 is affected. Before 0.7.0 the default store was \u003ccode\u003enil\u003c/code\u003e, which runs the library statelessly and provides no application-level replay protection at all, a documented property rather than part of this issue; those versions are affected only where a \u003ccode\u003e\"store\"\u003c/code\u003e was configured explicitly in \u003ccode\u003emethod_config\u003c/code\u003e.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable when `MPP.Methods.Tempo` broadcasts a `type=\"transaction\"` credential with a dedup store in place. From mpp 0.7.0 the dedup store is on by default (the app-started `MPP.Tempo.ConCacheStore`; opt out with `store: false`), so every default Tempo deployment from 0.7.0 before 0.16.2 is affected. Before 0.7.0 the default store was `nil`, which runs the library statelessly and provides no application-level replay protection at all, a documented property rather than part of this issue; those versions are affected only where a `\"store\"` was configured explicitly in `method_config`."
}
],
"value": "Reachable when MPP.Methods.Tempo broadcasts a type=\"transaction\" credential with a dedup store in place. From mpp 0.7.0 the dedup store is on by default (the app-started MPP.Tempo.ConCacheStore; opt out with store: false), so every default Tempo deployment from 0.7.0 before 0.16.2 is affected. Before 0.7.0 the default store was nil, which runs the library statelessly and provides no application-level replay protection at all, a documented property rather than part of this issue; those versions are affected only where a \"store\" was configured explicitly in method_config."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.16.2",
"versionStartIncluding": "0.2.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "E.FU"
},
{
"lang": "en",
"type": "remediation developer",
"value": "E.FU"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-15T15:20:56.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Unsafe Equivalence in Input in ZenHive mpp allows an unauthenticated remote client to pass the Tempo duplicate-submission gate twice with one signed transaction.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eMPP.Methods.Tempo\u003c/code\u003e reserves the pre-broadcast dedup slot on the caller-supplied hex in \u003ccode\u003ereserve_hash_atomic/2\u003c/code\u003e, keyed through \u003ccode\u003estore_key/1\u003c/code\u003e on \u003ccode\u003etx.raw\u003c/code\u003e rather than on a canonical form of the transaction. The deserializer stores the caller\u0027s hex verbatim and accepts both recovery-id encodings, so one signed transaction submitted once with \u003ccode\u003ev=27\u003c/code\u003e and once with \u003ccode\u003ev=0\u003c/code\u003e yields two distinct reserve keys, and both pass the reserve and reach the broadcast path. The plug-level credential replay store is deliberately carved out for \u003ccode\u003etempo\u003c/code\u003e in \u003ccode\u003elib/mpp/replay.ex\u003c/code\u003e, leaving this reserve as the only gate, and the post-broadcast mark writes the canonical hash key that the raw-keyed reserve never reads.\u003c/p\u003e\n\u003cp\u003eWhat the duplicate submission yields depends on the node: a nonce-reuse rejection fails closed, while a node that answers with the canonical hash for an already-known transaction returns a second valid \u003ccode\u003ePayment-Receipt\u003c/code\u003e for a single on-chain payment.\u003c/p\u003e\n\u003cp\u003eThis issue affects mpp: from 0.2.0 before 0.16.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Unsafe Equivalence in Input in ZenHive mpp allows an unauthenticated remote client to pass the Tempo duplicate-submission gate twice with one signed transaction.\n\n`MPP.Methods.Tempo` reserves the pre-broadcast dedup slot on the caller-supplied hex in `reserve_hash_atomic/2`, keyed through `store_key/1` on `tx.raw` rather than on a canonical form of the transaction. The deserializer stores the caller\u0027s hex verbatim and accepts both recovery-id encodings, so one signed transaction submitted once with `v=27` and once with `v=0` yields two distinct reserve keys, and both pass the reserve and reach the broadcast path. The plug-level credential replay store is deliberately carved out for `tempo` in `lib/mpp/replay.ex`, leaving this reserve as the only gate, and the post-broadcast mark writes the canonical hash key that the raw-keyed reserve never reads.\n\nWhat the duplicate submission yields depends on the node: a nonce-reuse rejection fails closed, while a node that answers with the canonical hash for an already-known transaction returns a second valid `Payment-Receipt` for a single on-chain payment.\n\nThis issue affects mpp: from 0.2.0 before 0.16.2."
}
],
"value": "Improper Validation of Unsafe Equivalence in Input in ZenHive mpp allows an unauthenticated remote client to pass the Tempo duplicate-submission gate twice with one signed transaction.\n\nMPP.Methods.Tempo reserves the pre-broadcast dedup slot on the caller-supplied hex in reserve_hash_atomic/2, keyed through store_key/1 on tx.raw rather than on a canonical form of the transaction. The deserializer stores the caller\u0027s hex verbatim and accepts both recovery-id encodings, so one signed transaction submitted once with v=27 and once with v=0 yields two distinct reserve keys, and both pass the reserve and reach the broadcast path. The plug-level credential replay store is deliberately carved out for tempo in lib/mpp/replay.ex, leaving this reserve as the only gate, and the post-broadcast mark writes the canonical hash key that the raw-keyed reserve never reads.\n\nWhat the duplicate submission yields depends on the node: a nonce-reuse rejection fails closed, while a node that answers with the canonical hash for an already-known transaction returns a second valid Payment-Receipt for a single on-chain payment.\n\nThis issue affects mpp: from 0.2.0 before 0.16.2."
}
],
"impacts": [
{
"capecId": "CAPEC-267",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eA client re-encodes the recovery id of a transaction it has already submitted and presents it again. The duplicate passes the only duplicate-submission gate the Tempo method has, and against a node that answers with the canonical hash for an already-known transaction the client is issued a second \u003ccode\u003ePayment-Receipt\u003c/code\u003e for one on-chain payment.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "A client re-encodes the recovery id of a transaction it has already submitted and presents it again. The duplicate passes the only duplicate-submission gate the Tempo method has, and against a node that answers with the canonical hash for an already-known transaction the client is issued a second `Payment-Receipt` for one on-chain payment."
}
],
"value": "A client re-encodes the recovery id of a transaction it has already submitted and presents it again. The duplicate passes the only duplicate-submission gate the Tempo method has, and against a node that answers with the canonical hash for an already-known transaction the client is issued a second Payment-Receipt for one on-chain payment."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1289",
"description": "CWE-1289 Improper Validation of Unsafe Equivalence in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T08:24:40.446Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/ZenHive/mpp/security/advisories/GHSA-8x7x-5j8g-8hcx"
},
{
"name": "EEF CNA record for CVE-2026-88255",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-88255.html"
},
{
"name": "OSV record EEF-CVE-2026-88255",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-88255"
},
{
"name": "Introducing commit f890466 in ZenHive/mpp",
"tags": [
"related"
],
"url": "https://github.com/ZenHive/mpp/commit/f8904666061fbab695874856d8fcd02c471dfe1b"
},
{
"name": "Fix commit e12bd4a in ZenHive/mpp",
"tags": [
"patch"
],
"url": "https://github.com/ZenHive/mpp/commit/e12bd4a1cea2e97c2a01fc059c48e5594a7b4a43"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "mpp Tempo keys its pre-broadcast dedup reserve on the caller-supplied transaction encoding, so a re-encoded signed transaction reserves a second slot"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-88255",
"datePublished": "2026-09-16T08:24:40.446Z",
"dateReserved": "2026-09-11T18:30:01.336Z",
"dateUpdated": "2026-09-16T14:49:57.782Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-89186 (GCVE-0-2026-89186)
Vulnerability from cvelistv5 – Published: 2026-09-16 08:24 – Updated: 2026-09-16 14:50
VLAI
EPSS
VEX
Title
mpp writes Payment-Receipt and Cache-Control before the wrapped application runs, letting a consumer's own Cache-Control expose paid responses to shared caches
Summary
Use of Cache Containing Sensitive Information in ZenHive mpp allows a shared HTTP cache to store a paid response and serve it to clients that never paid.
MPP.Plug.verify_credential in lib/mpp/plug.ex sets payment-receipt and cache-control: private on the connection before the wrapped application runs, and registers no register_before_send/2 callback. Plug.Conn.put_resp_header/3 replaces an existing header, so a mounting application that sets its own cache-control on the paid resource (for example public, max-age=3600) silently overrides the private the library relies on, and a CDN or reverse proxy can then store the paid 200 together with its Payment-Receipt and serve both to unpaid clients. The library-level guarantee is therefore defeatable by the application it protects. For the same reason a downstream non-2xx response still carried Payment-Receipt, issuing a receipt for a response that delivered no resource.
This issue affects mpp: from 0.1.0 before 0.16.2.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-16 14:50 UTC
CWE
- CWE-524 - Use of Cache Containing Sensitive Information
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/ZenHive/mpp/security/advisorie… | relatedvendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-89186.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-89186 | related |
| https://github.com/ZenHive/mpp/commit/2d4d1d94aae… | related |
| https://github.com/ZenHive/mpp/commit/2fd91a5ecbd… | patch |
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-89186",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-16T14:50:34.541725Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T14:50:44.399Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.MPP.Plug\u0027"
],
"packageName": "mpp",
"packageURL": "pkg:hex/mpp",
"product": "mpp",
"programFiles": [
"lib/mpp/plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.MPP.Plug\u0027:call/2"
}
],
"repo": "https://github.com/ZenHive/mpp",
"vendor": "ZenHive",
"versions": [
{
"lessThan": "0.16.2",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.MPP.Plug\u0027"
],
"packageName": "zenhive/mpp",
"packageURL": "pkg:github/zenhive/mpp",
"product": "mpp",
"programFiles": [
"lib/mpp/plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.MPP.Plug\u0027:call/2"
}
],
"repo": "https://github.com/ZenHive/mpp",
"vendor": "ZenHive",
"versions": [
{
"lessThan": "2fd91a5ecbd0b0ad2a4ac202b79659e8126dbc0b",
"status": "affected",
"version": "2d4d1d94aae7790ae0623063961adbeef171fa71",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only where the application mounted behind \u003ccode\u003eMPP.Plug\u003c/code\u003e sets its own \u003ccode\u003eCache-Control\u003c/code\u003e on the paid resource, overriding the \u003ccode\u003eprivate\u003c/code\u003e the library wrote, and a shared HTTP cache (CDN or reverse proxy) sits in front of that route. An application that sets no \u003ccode\u003eCache-Control\u003c/code\u003e of its own keeps the library\u0027s \u003ccode\u003eprivate\u003c/code\u003e and is not affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only where the application mounted behind `MPP.Plug` sets its own `Cache-Control` on the paid resource, overriding the `private` the library wrote, and a shared HTTP cache (CDN or reverse proxy) sits in front of that route. An application that sets no `Cache-Control` of its own keeps the library\u0027s `private` and is not affected."
}
],
"value": "Reachable only where the application mounted behind MPP.Plug sets its own Cache-Control on the paid resource, overriding the private the library wrote, and a shared HTTP cache (CDN or reverse proxy) sits in front of that route. An application that sets no Cache-Control of its own keeps the library\u0027s private and is not affected."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ZenHive:mpp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.16.2",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "E.FU"
},
{
"lang": "en",
"type": "remediation developer",
"value": "E.FU"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-09-15T15:22:44.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUse of Cache Containing Sensitive Information in ZenHive mpp allows a shared HTTP cache to store a paid response and serve it to clients that never paid.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eMPP.Plug.verify_credential\u003c/code\u003e in \u003ccode\u003elib/mpp/plug.ex\u003c/code\u003e sets \u003ccode\u003epayment-receipt\u003c/code\u003e and \u003ccode\u003ecache-control: private\u003c/code\u003e on the connection before the wrapped application runs, and registers no \u003ccode\u003eregister_before_send/2\u003c/code\u003e callback. \u003ccode\u003ePlug.Conn.put_resp_header/3\u003c/code\u003e replaces an existing header, so a mounting application that sets its own \u003ccode\u003ecache-control\u003c/code\u003e on the paid resource (for example \u003ccode\u003epublic, max-age=3600\u003c/code\u003e) silently overrides the \u003ccode\u003eprivate\u003c/code\u003e the library relies on, and a CDN or reverse proxy can then store the paid 200 together with its \u003ccode\u003ePayment-Receipt\u003c/code\u003e and serve both to unpaid clients. The library-level guarantee is therefore defeatable by the application it protects. For the same reason a downstream non-2xx response still carried \u003ccode\u003ePayment-Receipt\u003c/code\u003e, issuing a receipt for a response that delivered no resource.\u003c/p\u003e\n\u003cp\u003eThis issue affects mpp: from 0.1.0 before 0.16.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Use of Cache Containing Sensitive Information in ZenHive mpp allows a shared HTTP cache to store a paid response and serve it to clients that never paid.\n\n`MPP.Plug.verify_credential` in `lib/mpp/plug.ex` sets `payment-receipt` and `cache-control: private` on the connection before the wrapped application runs, and registers no `register_before_send/2` callback. `Plug.Conn.put_resp_header/3` replaces an existing header, so a mounting application that sets its own `cache-control` on the paid resource (for example `public, max-age=3600`) silently overrides the `private` the library relies on, and a CDN or reverse proxy can then store the paid 200 together with its `Payment-Receipt` and serve both to unpaid clients. The library-level guarantee is therefore defeatable by the application it protects. For the same reason a downstream non-2xx response still carried `Payment-Receipt`, issuing a receipt for a response that delivered no resource.\n\nThis issue affects mpp: from 0.1.0 before 0.16.2."
}
],
"value": "Use of Cache Containing Sensitive Information in ZenHive mpp allows a shared HTTP cache to store a paid response and serve it to clients that never paid.\n\nMPP.Plug.verify_credential in lib/mpp/plug.ex sets payment-receipt and cache-control: private on the connection before the wrapped application runs, and registers no register_before_send/2 callback. Plug.Conn.put_resp_header/3 replaces an existing header, so a mounting application that sets its own cache-control on the paid resource (for example public, max-age=3600) silently overrides the private the library relies on, and a CDN or reverse proxy can then store the paid 200 together with its Payment-Receipt and serve both to unpaid clients. The library-level guarantee is therefore defeatable by the application it protects. For the same reason a downstream non-2xx response still carried Payment-Receipt, issuing a receipt for a response that delivered no resource.\n\nThis issue affects mpp: from 0.1.0 before 0.16.2."
}
],
"impacts": [
{
"capecId": "CAPEC-204",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn unpaid client requesting the same URL through the shared cache receives the cached paid response, including the \u003ccode\u003ePayment-Receipt\u003c/code\u003e header issued to the paying client. Operators lose the revenue for every cache hit, and the receipt identifying a paid transaction is disclosed to third parties.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An unpaid client requesting the same URL through the shared cache receives the cached paid response, including the `Payment-Receipt` header issued to the paying client. Operators lose the revenue for every cache hit, and the receipt identifying a paid transaction is disclosed to third parties."
}
],
"value": "An unpaid client requesting the same URL through the shared cache receives the cached paid response, including the Payment-Receipt header issued to the paying client. Operators lose the revenue for every cache hit, and the receipt identifying a paid transaction is disclosed to third parties."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "LOW",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-524",
"description": "CWE-524 Use of Cache Containing Sensitive Information",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-16T08:24:15.058Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/ZenHive/mpp/security/advisories/GHSA-82qh-vrvm-gqvc"
},
{
"name": "EEF CNA record for CVE-2026-89186",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-89186.html"
},
{
"name": "OSV record EEF-CVE-2026-89186",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-89186"
},
{
"name": "Introducing commit 2d4d1d9 in ZenHive/mpp",
"tags": [
"related"
],
"url": "https://github.com/ZenHive/mpp/commit/2d4d1d94aae7790ae0623063961adbeef171fa71"
},
{
"name": "Fix commit 2fd91a5 in ZenHive/mpp",
"tags": [
"patch"
],
"url": "https://github.com/ZenHive/mpp/commit/2fd91a5ecbd0b0ad2a4ac202b79659e8126dbc0b"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "mpp writes Payment-Receipt and Cache-Control before the wrapped application runs, letting a consumer\u0027s own Cache-Control expose paid responses to shared caches",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eIn the application mounted behind \u003ccode\u003eMPP.Plug\u003c/code\u003e, stop setting \u003ccode\u003eCache-Control\u003c/code\u003e on paid routes so the library\u0027s \u003ccode\u003eprivate\u003c/code\u003e survives to the response, or set a directive that is itself safe for a shared cache (\u003ccode\u003eprivate\u003c/code\u003e, or \u003ccode\u003eno-store\u003c/code\u003e). Where the application must set its own caching policy, configure the CDN or reverse proxy not to cache responses carrying a \u003ccode\u003ePayment-Receipt\u003c/code\u003e header.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "In the application mounted behind `MPP.Plug`, stop setting `Cache-Control` on paid routes so the library\u0027s `private` survives to the response, or set a directive that is itself safe for a shared cache (`private`, or `no-store`). Where the application must set its own caching policy, configure the CDN or reverse proxy not to cache responses carrying a `Payment-Receipt` header."
}
],
"value": "In the application mounted behind MPP.Plug, stop setting Cache-Control on paid routes so the library\u0027s private survives to the response, or set a directive that is itself safe for a shared cache (private, or no-store). Where the application must set its own caching policy, configure the CDN or reverse proxy not to cache responses carrying a Payment-Receipt header."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-89186",
"datePublished": "2026-09-16T08:24:15.058Z",
"dateReserved": "2026-09-11T19:00:02.549Z",
"dateUpdated": "2026-09-16T14:50:44.399Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-77866 (GCVE-0-2026-77866)
Vulnerability from cvelistv5 – Published: 2026-09-15 15:38 – Updated: 2026-09-15 15:39
VLAI
EPSS
VEX
Title
SSRF protection bypass in safeurl via IPv6 addresses and unresolvable hosts
Summary
Server-Side Request Forgery (SSRF) vulnerability in Slab safeurl allows an attacker who controls a validated URL to reach internal network destinations the library is configured to block.
Only IPv4 addresses are matched against the reserved ranges and the blocklist. Every other address is treated as matching nothing, so a destination that is rejected in its IPv4 form is accepted when written as an IPv6 address, IPv6 entries in the blocklist never match, and a host that resolves to no IPv4 address is accepted regardless of where it points. Deployments that rely on the allowlist instead are unaffected, because there an unmatched address is rejected.
This issue affects safeurl: from 0.1.0 onward.
Severity
Assigner
References
3 references
| URL | Tags |
|---|---|
| https://cna.erlef.org/cves/CVE-2026-77866.html | relatedthird-party-advisory |
| https://osv.dev/vulnerability/EEF-CVE-2026-77866 | related |
| https://github.com/slab/safeurl-elixir/commit/fea… | related |
Impacted products
Date Public
2026-09-15 15:38
{
"containers": {
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.SafeURL\u0027"
],
"packageName": "safeurl",
"packageURL": "pkg:hex/safeurl",
"product": "safeurl",
"programFiles": [
"lib/safeurl/safeurl.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.SafeURL\u0027:validate/2"
},
{
"name": "\u0027Elixir.SafeURL\u0027:allowed?/2"
}
],
"repo": "https://github.com/slab/safeurl-elixir",
"vendor": "Slab",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.SafeURL\u0027"
],
"packageName": "slab/safeurl-elixir",
"packageURL": "pkg:github/slab/safeurl-elixir",
"product": "safeurl",
"programFiles": [
"lib/safeurl/safeurl.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.SafeURL\u0027:validate/2"
},
{
"name": "\u0027Elixir.SafeURL\u0027:allowed?/2"
}
],
"repo": "https://github.com/slab/safeurl-elixir",
"vendor": "Slab",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "feabbd0a13f83028ab24b71710526e9da9841f70",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Mathias Polligkeit"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"datePublic": "2026-09-15T15:38:16.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eServer-Side Request Forgery (SSRF) vulnerability in Slab safeurl allows an attacker who controls a validated URL to reach internal network destinations the library is configured to block.\u003c/p\u003e\n\u003cp\u003eOnly IPv4 addresses are matched against the reserved ranges and the blocklist. Every other address is treated as matching nothing, so a destination that is rejected in its IPv4 form is accepted when written as an IPv6 address, IPv6 entries in the blocklist never match, and a host that resolves to no IPv4 address is accepted regardless of where it points. Deployments that rely on the allowlist instead are unaffected, because there an unmatched address is rejected.\u003c/p\u003e\n\u003cp\u003eThis issue affects safeurl: from 0.1.0 onward.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Server-Side Request Forgery (SSRF) vulnerability in Slab safeurl allows an attacker who controls a validated URL to reach internal network destinations the library is configured to block.\n\nOnly IPv4 addresses are matched against the reserved ranges and the blocklist. Every other address is treated as matching nothing, so a destination that is rejected in its IPv4 form is accepted when written as an IPv6 address, IPv6 entries in the blocklist never match, and a host that resolves to no IPv4 address is accepted regardless of where it points. Deployments that rely on the allowlist instead are unaffected, because there an unmatched address is rejected.\n\nThis issue affects safeurl: from 0.1.0 onward."
}
],
"value": "Server-Side Request Forgery (SSRF) vulnerability in Slab safeurl allows an attacker who controls a validated URL to reach internal network destinations the library is configured to block.\n\nOnly IPv4 addresses are matched against the reserved ranges and the blocklist. Every other address is treated as matching nothing, so a destination that is rejected in its IPv4 form is accepted when written as an IPv6 address, IPv6 entries in the blocklist never match, and a host that resolves to no IPv4 address is accepted regardless of where it points. Deployments that rely on the allowlist instead are unaffected, because there an unmatched address is rejected.\n\nThis issue affects safeurl: from 0.1.0 onward."
}
],
"impacts": [
{
"capecId": "CAPEC-664",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-664 Server Side Request Forgery"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "HIGH",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-918",
"description": "CWE-918 Server-Side Request Forgery (SSRF)",
"lang": "en",
"type": "CWE"
}
]
},
{
"descriptions": [
{
"cweId": "CWE-636",
"description": "CWE-636 Not Failing Securely (\u0027Failing Open\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-15T15:39:37.321Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "EEF CNA record for CVE-2026-77866",
"tags": [
"related",
"third-party-advisory"
],
"url": "https://cna.erlef.org/cves/CVE-2026-77866.html"
},
{
"name": "OSV record EEF-CVE-2026-77866",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-77866"
},
{
"name": "Introducing commit feabbd0 in slab/safeurl-elixir",
"tags": [
"related"
],
"url": "https://github.com/slab/safeurl-elixir/commit/feabbd0a13f83028ab24b71710526e9da9841f70"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "SSRF protection bypass in safeurl via IPv6 addresses and unresolvable hosts"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-77866",
"datePublished": "2026-09-15T15:38:15.886Z",
"dateReserved": "2026-08-30T00:00:01.985Z",
"dateUpdated": "2026-09-15T15:39:37.321Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-77972 (GCVE-0-2026-77972)
Vulnerability from cvelistv5 – Published: 2026-09-15 15:37 – Updated: 2026-09-15 15:37
VLAI
EPSS
VEX
Title
safeurl validated address is not bound to the request, allowing DNS rebinding
Summary
Time-of-check Time-of-use (TOCTOU) Race Condition in Slab safeurl allows an attacker who controls a hostname's DNS responses to reach internal network destinations that validation rejected.
Validation returns a verdict and not the address it approved, so the HTTP clients the library ships receive the original hostname and resolve it a second time when the request is made. An attacker who controls the authoritative DNS for a name can answer the first lookup with a permitted address and the second with a blocked one, and the request then reaches a destination validation never approved. The same window opens without an attacker whenever a name legitimately resolves to different addresses across lookups, such as short record lifetimes or rotation between several addresses.
This issue affects safeurl: from 0.1.0 onward.
Severity
CWE
- CWE-367 - Time-of-check Time-of-use (TOCTOU) Race Condition
Assigner
References
3 references
| URL | Tags |
|---|---|
| https://cna.erlef.org/cves/CVE-2026-77972.html | relatedthird-party-advisory |
| https://osv.dev/vulnerability/EEF-CVE-2026-77972 | related |
| https://github.com/slab/safeurl-elixir/commit/fea… | related |
Impacted products
{
"containers": {
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.SafeURL\u0027",
"\u0027Elixir.SafeURL.HTTPoison\u0027",
"\u0027Elixir.SafeURL.TeslaMiddleware\u0027"
],
"packageName": "safeurl",
"packageURL": "pkg:hex/safeurl",
"product": "safeurl",
"programFiles": [
"lib/safeurl/safeurl.ex",
"lib/safeurl/httpoison.ex",
"lib/safeurl/tesla_middleware.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.SafeURL\u0027:validate/2"
},
{
"name": "\u0027Elixir.SafeURL.HTTPoison\u0027:get/3"
},
{
"name": "\u0027Elixir.SafeURL.TeslaMiddleware\u0027:call/3"
}
],
"repo": "https://github.com/slab/safeurl-elixir",
"vendor": "Slab",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.SafeURL\u0027",
"\u0027Elixir.SafeURL.HTTPoison\u0027",
"\u0027Elixir.SafeURL.TeslaMiddleware\u0027"
],
"packageName": "slab/safeurl-elixir",
"packageURL": "pkg:github/slab/safeurl-elixir",
"product": "safeurl",
"programFiles": [
"lib/safeurl/safeurl.ex",
"lib/safeurl/httpoison.ex",
"lib/safeurl/tesla_middleware.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.SafeURL\u0027:validate/2"
},
{
"name": "\u0027Elixir.SafeURL.HTTPoison\u0027:get/3"
},
{
"name": "\u0027Elixir.SafeURL.TeslaMiddleware\u0027:call/3"
}
],
"repo": "https://github.com/slab/safeurl-elixir",
"vendor": "Slab",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "feabbd0a13f83028ab24b71710526e9da9841f70",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:slab:safeurl:*:*:*:*:*:*:*:*",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eTime-of-check Time-of-use (TOCTOU) Race Condition in Slab safeurl allows an attacker who controls a hostname\u0027s DNS responses to reach internal network destinations that validation rejected.\u003c/p\u003e\n\u003cp\u003eValidation returns a verdict and not the address it approved, so the HTTP clients the library ships receive the original hostname and resolve it a second time when the request is made. An attacker who controls the authoritative DNS for a name can answer the first lookup with a permitted address and the second with a blocked one, and the request then reaches a destination validation never approved. The same window opens without an attacker whenever a name legitimately resolves to different addresses across lookups, such as short record lifetimes or rotation between several addresses.\u003c/p\u003e\n\u003cp\u003eThis issue affects safeurl: from 0.1.0 onward.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Time-of-check Time-of-use (TOCTOU) Race Condition in Slab safeurl allows an attacker who controls a hostname\u0027s DNS responses to reach internal network destinations that validation rejected.\n\nValidation returns a verdict and not the address it approved, so the HTTP clients the library ships receive the original hostname and resolve it a second time when the request is made. An attacker who controls the authoritative DNS for a name can answer the first lookup with a permitted address and the second with a blocked one, and the request then reaches a destination validation never approved. The same window opens without an attacker whenever a name legitimately resolves to different addresses across lookups, such as short record lifetimes or rotation between several addresses.\n\nThis issue affects safeurl: from 0.1.0 onward."
}
],
"value": "Time-of-check Time-of-use (TOCTOU) Race Condition in Slab safeurl allows an attacker who controls a hostname\u0027s DNS responses to reach internal network destinations that validation rejected.\n\nValidation returns a verdict and not the address it approved, so the HTTP clients the library ships receive the original hostname and resolve it a second time when the request is made. An attacker who controls the authoritative DNS for a name can answer the first lookup with a permitted address and the second with a blocked one, and the request then reaches a destination validation never approved. The same window opens without an attacker whenever a name legitimately resolves to different addresses across lookups, such as short record lifetimes or rotation between several addresses.\n\nThis issue affects safeurl: from 0.1.0 onward."
}
],
"impacts": [
{
"capecId": "CAPEC-664",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-664 Server Side Request Forgery"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "HIGH",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "HIGH",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-367",
"description": "CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-15T15:37:49.948Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "EEF CNA record for CVE-2026-77972",
"tags": [
"related",
"third-party-advisory"
],
"url": "https://cna.erlef.org/cves/CVE-2026-77972.html"
},
{
"name": "OSV record EEF-CVE-2026-77972",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-77972"
},
{
"name": "Introducing commit feabbd0 in slab/safeurl-elixir",
"tags": [
"related"
],
"url": "https://github.com/slab/safeurl-elixir/commit/feabbd0a13f83028ab24b71710526e9da9841f70"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "safeurl validated address is not bound to the request, allowing DNS rebinding"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-77972",
"datePublished": "2026-09-15T15:37:49.948Z",
"dateReserved": "2026-08-24T15:45:02.127Z",
"dateUpdated": "2026-09-15T15:37:49.948Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-78216 (GCVE-0-2026-78216)
Vulnerability from cvelistv5 – Published: 2026-09-08 16:42 – Updated: 2026-09-08 17:27
VLAI
EPSS
VEX
Title
AshLua eval read operations can read field-policy-protected fields via aggregates
Summary
AshLua exposes Ash read actions to Lua scripts run through an eval action. A read call accepts an operation (list, min, max, first, sum, avg) that builds an ad-hoc Ash.Query.Aggregate over a named field and returns its raw value.
Ash field policies redact forbidden fields on returned records (replacing them with %Ash.ForbiddenField{}), but that redaction does not apply to aggregate values. A script could therefore read a field the calling actor's field policies forbid by requesting it as an aggregate instead of as a field. This includes fields that are public? true but restricted per-actor by a field policy, such as sensitive PII. The prior hardening only enforced the exposed-field allow-list (field visibility), which is a separate axis from per-actor field-policy authorization.
The fix authorizes the aggregated field against the resource's field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.
This issue affects ash_lua: from 0.1.0 before 0.2.2.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 17:26 UTC
CWE
- CWE-1220 - Insufficient Granularity of Access Control
Assigner
References
5 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_lua |
Affected:
0.1.0 , < 0.2.2
(semver)
cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:* |
|
| ash-project | ash_lua |
Affected:
8675e47cca81f36594083a7e63379bac9e123e72 , < 266a5dcc56d5015b6d316c10606169e753b07450
(git)
cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-78216",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T17:26:34.675766Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T17:27:08.856Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshLua.Runtime\u0027"
],
"packageName": "ash_lua",
"packageURL": "pkg:hex/ash_lua",
"product": "ash_lua",
"programFiles": [
"lib/ash_lua/runtime.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshLua.Runtime\u0027:run_read_operation/5"
}
],
"repo": "https://github.com/ash-project/ash_lua",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.2.2",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshLua.Runtime\u0027"
],
"packageName": "ash-project/ash_lua",
"packageURL": "pkg:github/ash-project/ash_lua",
"product": "ash_lua",
"programFiles": [
"lib/ash_lua/runtime.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshLua.Runtime\u0027:run_read_operation/5"
}
],
"repo": "https://github.com/ash-project/ash_lua",
"vendor": "ash-project",
"versions": [
{
"lessThan": "266a5dcc56d5015b6d316c10606169e753b07450",
"status": "affected",
"version": "8675e47cca81f36594083a7e63379bac9e123e72",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when an application exposes an AshLua \u003ccode\u003eeval\u003c/code\u003e action over a resource whose field policies restrict a field that the calling actor can still name as an operation aggregate (for example a \u003ccode\u003epublic? true\u003c/code\u003e but field-policy-protected attribute).\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when an application exposes an AshLua `eval` action over a resource whose field policies restrict a field that the calling actor can still name as an operation aggregate (for example a `public? true` but field-policy-protected attribute)."
}
],
"value": "Reachable only when an application exposes an AshLua eval action over a resource whose field policies restrict a field that the calling actor can still name as an operation aggregate (for example a public? true but field-policy-protected attribute)."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.2.2",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Aaron Hong / Remedy"
}
],
"dateAssigned": "2026-09-08T15:43:48.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAshLua exposes Ash read actions to Lua scripts run through an \u003ccode\u003eeval\u003c/code\u003e action. A read call accepts an \u003ccode\u003eoperation\u003c/code\u003e (\u003ccode\u003elist\u003c/code\u003e, \u003ccode\u003emin\u003c/code\u003e, \u003ccode\u003emax\u003c/code\u003e, \u003ccode\u003efirst\u003c/code\u003e, \u003ccode\u003esum\u003c/code\u003e, \u003ccode\u003eavg\u003c/code\u003e) that builds an ad-hoc \u003ccode\u003eAsh.Query.Aggregate\u003c/code\u003e over a named field and returns its raw value.\u003c/p\u003e\n\u003cp\u003eAsh field policies redact forbidden fields on returned records (replacing them with \u003ccode\u003e%Ash.ForbiddenField{}\u003c/code\u003e), but that redaction does not apply to aggregate values. A script could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate instead of as a field. This includes fields that are \u003ccode\u003epublic? true\u003c/code\u003e but restricted per-actor by a field policy, such as sensitive PII. The prior hardening only enforced the exposed-field allow-list (field visibility), which is a separate axis from per-actor field-policy authorization.\u003c/p\u003e\n\u003cp\u003eThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_lua: from 0.1.0 before 0.2.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "AshLua exposes Ash read actions to Lua scripts run through an `eval` action. A read call accepts an `operation` (`list`, `min`, `max`, `first`, `sum`, `avg`) that builds an ad-hoc `Ash.Query.Aggregate` over a named field and returns its raw value.\n\nAsh field policies redact forbidden fields on returned records (replacing them with `%Ash.ForbiddenField{}`), but that redaction does not apply to aggregate values. A script could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate instead of as a field. This includes fields that are `public? true` but restricted per-actor by a field policy, such as sensitive PII. The prior hardening only enforced the exposed-field allow-list (field visibility), which is a separate axis from per-actor field-policy authorization.\n\nThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\n\nThis issue affects ash_lua: from 0.1.0 before 0.2.2."
}
],
"value": "AshLua exposes Ash read actions to Lua scripts run through an eval action. A read call accepts an operation (list, min, max, first, sum, avg) that builds an ad-hoc Ash.Query.Aggregate over a named field and returns its raw value.\n\nAsh field policies redact forbidden fields on returned records (replacing them with %Ash.ForbiddenField{}), but that redaction does not apply to aggregate values. A script could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate instead of as a field. This includes fields that are public? true but restricted per-actor by a field policy, such as sensitive PII. The prior hardening only enforced the exposed-field allow-list (field visibility), which is a separate axis from per-actor field-policy authorization.\n\nThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\n\nThis issue affects ash_lua: from 0.1.0 before 0.2.2."
}
],
"impacts": [
{
"capecId": "CAPEC-1",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6,
"baseSeverity": "MEDIUM",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1220",
"description": "CWE-1220 Insufficient Granularity of Access Control",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T16:42:20.908Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GHSA-5whv-8rcp-x33j",
"tags": [
"vendor-advisory"
],
"url": "https://github.com/ash-project/ash_lua/security/advisories/GHSA-5whv-8rcp-x33j"
},
{
"name": "EEF CNA record for CVE-2026-78216",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-78216.html"
},
{
"name": "OSV record EEF-CVE-2026-78216",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-78216"
},
{
"name": "Introducing commit 8675e47 in ash-project/ash_lua",
"tags": [
"related"
],
"url": "https://github.com/ash-project/ash_lua/commit/8675e47cca81f36594083a7e63379bac9e123e72"
},
{
"name": "Fix commit 266a5dc in ash-project/ash_lua",
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_lua/commit/266a5dcc56d5015b6d316c10606169e753b07450"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "AshLua eval read operations can read field-policy-protected fields via aggregates"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-78216",
"datePublished": "2026-09-08T16:42:20.908Z",
"dateReserved": "2026-08-31T00:45:02.446Z",
"dateUpdated": "2026-09-08T17:27:08.856Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-78230 (GCVE-0-2026-78230)
Vulnerability from cvelistv5 – Published: 2026-09-08 16:41 – Updated: 2026-09-08 17:33
VLAI
EPSS
VEX
Title
AshAi aggregate tool can read field-policy-protected fields
Summary
AshAi exposes Ash read actions to language-model tool calls. The read tool accepts an aggregate result type (min, max, sum, avg) that builds an ad-hoc Ash.Query.Aggregate over a named field and returns its raw value.
Ash field policies redact forbidden fields on returned records (replacing them with %Ash.ForbiddenField{}), but that redaction does not apply to aggregate values. A tool caller could therefore read a field the calling actor's field policies forbid by requesting it as an aggregate; min/max in particular return an actual field value. This includes fields that are public? true but restricted per-actor by a field policy, such as sensitive PII. The tool's existing check only required the field to be public, which is a separate axis from per-actor field-policy authorization.
The fix authorizes the aggregated field against the resource's field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.
This issue affects ash_ai: from 0.1.0 before 1.0.3.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 17:33 UTC
CWE
- CWE-1220 - Insufficient Granularity of Access Control
Assigner
References
5 references
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_ai |
Affected:
0.1.0 , < 1.0.3
(semver)
cpe:2.3:a:ash-project:ash_ai:*:*:*:*:*:*:*:* |
|
| ash-project | ash_ai |
Affected:
2ba234b50946a3b8116190c8467f9f4dfa5edce7 , < 9c02de581625c342c9870a672830bff28c1d701e
(git)
cpe:2.3:a:ash-project:ash_ai:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-78230",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T17:33:49.017554Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T17:33:57.604Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_ai:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAi.Tool.Execution\u0027"
],
"packageName": "ash_ai",
"packageURL": "pkg:hex/ash_ai",
"product": "ash_ai",
"programFiles": [
"lib/ash_ai/tool/execution.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAi.Tool.Execution\u0027:execute_read/4"
}
],
"repo": "https://github.com/ash-project/ash_ai",
"vendor": "ash-project",
"versions": [
{
"lessThan": "1.0.3",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_ai:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAi.Tool.Execution\u0027"
],
"packageName": "ash-project/ash_ai",
"packageURL": "pkg:github/ash-project/ash_ai",
"product": "ash_ai",
"programFiles": [
"lib/ash_ai/tool/execution.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAi.Tool.Execution\u0027:execute_read/4"
}
],
"repo": "https://github.com/ash-project/ash_ai",
"vendor": "ash-project",
"versions": [
{
"lessThan": "9c02de581625c342c9870a672830bff28c1d701e",
"status": "affected",
"version": "2ba234b50946a3b8116190c8467f9f4dfa5edce7",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when an application exposes an AshAi read tool over a resource whose field policies restrict a field that the calling actor can still name as an aggregate (for example a \u003ccode\u003epublic? true\u003c/code\u003e but field-policy-protected attribute).\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when an application exposes an AshAi read tool over a resource whose field policies restrict a field that the calling actor can still name as an aggregate (for example a `public? true` but field-policy-protected attribute)."
}
],
"value": "Reachable only when an application exposes an AshAi read tool over a resource whose field policies restrict a field that the calling actor can still name as an aggregate (for example a public? true but field-policy-protected attribute)."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_ai:*:*:*:*:*:*:*:*",
"versionEndExcluding": "1.0.3",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Aaron Hong / Remedy"
}
],
"dateAssigned": "2026-09-08T15:44:25.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAshAi exposes Ash read actions to language-model tool calls. The read tool accepts an aggregate result type (\u003ccode\u003emin\u003c/code\u003e, \u003ccode\u003emax\u003c/code\u003e, \u003ccode\u003esum\u003c/code\u003e, \u003ccode\u003eavg\u003c/code\u003e) that builds an ad-hoc \u003ccode\u003eAsh.Query.Aggregate\u003c/code\u003e over a named field and returns its raw value.\u003c/p\u003e\n\u003cp\u003eAsh field policies redact forbidden fields on returned records (replacing them with \u003ccode\u003e%Ash.ForbiddenField{}\u003c/code\u003e), but that redaction does not apply to aggregate values. A tool caller could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate; \u003ccode\u003emin\u003c/code\u003e/\u003ccode\u003emax\u003c/code\u003e in particular return an actual field value. This includes fields that are \u003ccode\u003epublic? true\u003c/code\u003e but restricted per-actor by a field policy, such as sensitive PII. The tool\u0027s existing check only required the field to be public, which is a separate axis from per-actor field-policy authorization.\u003c/p\u003e\n\u003cp\u003eThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_ai: from 0.1.0 before 1.0.3.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "AshAi exposes Ash read actions to language-model tool calls. The read tool accepts an aggregate result type (`min`, `max`, `sum`, `avg`) that builds an ad-hoc `Ash.Query.Aggregate` over a named field and returns its raw value.\n\nAsh field policies redact forbidden fields on returned records (replacing them with `%Ash.ForbiddenField{}`), but that redaction does not apply to aggregate values. A tool caller could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate; `min`/`max` in particular return an actual field value. This includes fields that are `public? true` but restricted per-actor by a field policy, such as sensitive PII. The tool\u0027s existing check only required the field to be public, which is a separate axis from per-actor field-policy authorization.\n\nThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\n\nThis issue affects ash_ai: from 0.1.0 before 1.0.3."
}
],
"value": "AshAi exposes Ash read actions to language-model tool calls. The read tool accepts an aggregate result type (min, max, sum, avg) that builds an ad-hoc Ash.Query.Aggregate over a named field and returns its raw value.\n\nAsh field policies redact forbidden fields on returned records (replacing them with %Ash.ForbiddenField{}), but that redaction does not apply to aggregate values. A tool caller could therefore read a field the calling actor\u0027s field policies forbid by requesting it as an aggregate; min/max in particular return an actual field value. This includes fields that are public? true but restricted per-actor by a field policy, such as sensitive PII. The tool\u0027s existing check only required the field to be public, which is a separate axis from per-actor field-policy authorization.\n\nThe fix authorizes the aggregated field against the resource\u0027s field policies, so aggregating over a field the actor may not see is refused or scoped to the rows where it is visible.\n\nThis issue affects ash_ai: from 0.1.0 before 1.0.3."
}
],
"impacts": [
{
"capecId": "CAPEC-1",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-1 Accessing Functionality Not Properly Constrained by ACLs"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6,
"baseSeverity": "MEDIUM",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1220",
"description": "CWE-1220 Insufficient Granularity of Access Control",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T16:41:45.975Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GHSA-v5rw-36x5-r5vx",
"tags": [
"vendor-advisory"
],
"url": "https://github.com/ash-project/ash_ai/security/advisories/GHSA-v5rw-36x5-r5vx"
},
{
"name": "EEF CNA record for CVE-2026-78230",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-78230.html"
},
{
"name": "OSV record EEF-CVE-2026-78230",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-78230"
},
{
"name": "Introducing commit 2ba234b in ash-project/ash_ai",
"tags": [
"related"
],
"url": "https://github.com/ash-project/ash_ai/commit/2ba234b50946a3b8116190c8467f9f4dfa5edce7"
},
{
"name": "Fix commit 9c02de5 in ash-project/ash_ai",
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_ai/commit/9c02de581625c342c9870a672830bff28c1d701e"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "AshAi aggregate tool can read field-policy-protected fields"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-78230",
"datePublished": "2026-09-08T16:41:45.975Z",
"dateReserved": "2026-08-31T00:45:02.439Z",
"dateUpdated": "2026-09-08T17:33:57.604Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82710 (GCVE-0-2026-82710)
Vulnerability from cvelistv5 – Published: 2026-09-08 00:23 – Updated: 2026-09-08 14:45
VLAI
EPSS
VEX
Title
Terminal escape sequence injection in mix usage_rules.search_docs via package documentation metadata
Summary
Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project usage_rules allows a malicious package publisher to inject terminal control sequences into the output of mix usage_rules.search_docs.
mix usage_rules.search_docs searches Hex documentation through search.hexdocs.pm, which indexes the documentation of every published package, and prints the matching results (title, package, type, doc reference, and highlighted snippets) to the terminal. The formatter in Mix.Tasks.UsageRules.SearchDocs interpolated those publisher-controlled fields verbatim, neutralizing no terminal control characters; the only transform it applied adds escape sequences rather than removing them. A malicious package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns, OSC 52 clipboard writes) in its indexed documentation, so when a developer runs a search that surfaces those docs the sequences reach the terminal unchanged — forging the displayed hexdocs URL or a suggested command, hiding text, or writing to the clipboard. No authentication or privileged position is required; only publishing a package.
This issue affects usage_rules: from 0.1.18 before 1.2.8.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:45 UTC
CWE
- CWE-150 - Improper Neutralization of Escape, Meta, or Control Sequences
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/usage_rules/securi… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82710.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82710 | related |
| https://github.com/ash-project/usage_rules/commit… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | usage_rules |
Affected:
0.1.18 , < 1.2.8
(semver)
cpe:2.3:a:ash-project:usage_rules:*:*:*:*:*:*:*:* |
|
| ash-project | usage_rules |
Affected:
2da7a99536041d63ec1f391d019565789a59595f , < 3b8ebb4117d3272bbd436e6c2432113ba6685dbb
(git)
cpe:2.3:a:ash-project:usage_rules:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82710",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:45:15.853850Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:45:23.177Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:usage_rules:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Mix.Tasks.UsageRules.SearchDocs\u0027"
],
"packageName": "usage_rules",
"packageURL": "pkg:hex/usage_rules",
"product": "usage_rules",
"programFiles": [
"lib/mix/tasks/usage_rules.search_docs.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Mix.Tasks.UsageRules.SearchDocs\u0027:format_search_result_markdown/4"
}
],
"repo": "https://github.com/ash-project/usage_rules",
"vendor": "ash-project",
"versions": [
{
"lessThan": "1.2.8",
"status": "affected",
"version": "0.1.18",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:usage_rules:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Mix.Tasks.UsageRules.SearchDocs\u0027"
],
"packageName": "ash-project/usage_rules",
"packageURL": "pkg:github/ash-project/usage_rules",
"product": "usage_rules",
"programFiles": [
"lib/mix/tasks/usage_rules.search_docs.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Mix.Tasks.UsageRules.SearchDocs\u0027:format_search_result_markdown/4"
}
],
"repo": "https://github.com/ash-project/usage_rules",
"vendor": "ash-project",
"versions": [
{
"lessThan": "3b8ebb4117d3272bbd436e6c2432113ba6685dbb",
"status": "affected",
"version": "2da7a99536041d63ec1f391d019565789a59595f",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when a developer runs \u003ccode\u003emix usage_rules.search_docs\u003c/code\u003e in a terminal emulator that interprets ANSI escape sequences and the results include documentation from an attacker-published package (for example a broad \u003ccode\u003e--everywhere\u003c/code\u003e search).\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when a developer runs `mix usage_rules.search_docs` in a terminal emulator that interprets ANSI escape sequences and the results include documentation from an attacker-published package (for example a broad `--everywhere` search)."
}
],
"value": "Reachable only when a developer runs mix usage_rules.search_docs in a terminal emulator that interprets ANSI escape sequences and the results include documentation from an attacker-published package (for example a broad --everywhere search)."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:usage_rules:*:*:*:*:*:*:*:*",
"versionEndExcluding": "1.2.8",
"versionStartIncluding": "0.1.18",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project usage_rules allows a malicious package publisher to inject terminal control sequences into the output of \u003ccode\u003emix usage_rules.search_docs\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003emix usage_rules.search_docs\u003c/code\u003e searches Hex documentation through \u003ccode\u003esearch.hexdocs.pm\u003c/code\u003e, which indexes the documentation of every published package, and prints the matching results (title, package, type, doc reference, and highlighted snippets) to the terminal. The formatter in \u003ccode\u003eMix.Tasks.UsageRules.SearchDocs\u003c/code\u003e interpolated those publisher-controlled fields verbatim, neutralizing no terminal control characters; the only transform it applied adds escape sequences rather than removing them. A malicious package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns, OSC 52 clipboard writes) in its indexed documentation, so when a developer runs a search that surfaces those docs the sequences reach the terminal unchanged \u2014 forging the displayed hexdocs URL or a suggested command, hiding text, or writing to the clipboard. No authentication or privileged position is required; only publishing a package.\u003c/p\u003e\n\u003cp\u003eThis issue affects usage_rules: from 0.1.18 before 1.2.8.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project usage_rules allows a malicious package publisher to inject terminal control sequences into the output of `mix usage_rules.search_docs`.\n\n`mix usage_rules.search_docs` searches Hex documentation through `search.hexdocs.pm`, which indexes the documentation of every published package, and prints the matching results (title, package, type, doc reference, and highlighted snippets) to the terminal. The formatter in `Mix.Tasks.UsageRules.SearchDocs` interpolated those publisher-controlled fields verbatim, neutralizing no terminal control characters; the only transform it applied adds escape sequences rather than removing them. A malicious package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns, OSC 52 clipboard writes) in its indexed documentation, so when a developer runs a search that surfaces those docs the sequences reach the terminal unchanged \u2014 forging the displayed hexdocs URL or a suggested command, hiding text, or writing to the clipboard. No authentication or privileged position is required; only publishing a package.\n\nThis issue affects usage_rules: from 0.1.18 before 1.2.8."
}
],
"value": "Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project usage_rules allows a malicious package publisher to inject terminal control sequences into the output of mix usage_rules.search_docs.\n\nmix usage_rules.search_docs searches Hex documentation through search.hexdocs.pm, which indexes the documentation of every published package, and prints the matching results (title, package, type, doc reference, and highlighted snippets) to the terminal. The formatter in Mix.Tasks.UsageRules.SearchDocs interpolated those publisher-controlled fields verbatim, neutralizing no terminal control characters; the only transform it applied adds escape sequences rather than removing them. A malicious package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns, OSC 52 clipboard writes) in its indexed documentation, so when a developer runs a search that surfaces those docs the sequences reach the terminal unchanged \u2014 forging the displayed hexdocs URL or a suggested command, hiding text, or writing to the clipboard. No authentication or privileged position is required; only publishing a package.\n\nThis issue affects usage_rules: from 0.1.18 before 1.2.8."
}
],
"impacts": [
{
"capecId": "CAPEC-93",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-93 Log Injection-Tampering-Forging"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 2.3,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "PASSIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-150",
"description": "CWE-150 Improper Neutralization of Escape, Meta, or Control Sequences",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T00:23:36.912Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/usage_rules/security/advisories/GHSA-j59f-776f-23hp"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82710.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82710"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/usage_rules/commit/3b8ebb4117d3272bbd436e6c2432113ba6685dbb"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Terminal escape sequence injection in mix usage_rules.search_docs via package documentation metadata"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82710",
"datePublished": "2026-09-08T00:23:36.912Z",
"dateReserved": "2026-09-07T20:30:01.990Z",
"dateUpdated": "2026-09-08T14:45:23.177Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82584 (GCVE-0-2026-82584)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:54 – Updated: 2026-09-08 14:44
VLAI
EPSS
VEX
Title
Terminal escape sequence injection in the mix igniter.install confirmation prompt via package metadata
Summary
Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project igniter allows a malicious package publisher to forge the mix igniter.install confirmation prompt.
mix igniter.install prints a confirmation panel (an anti-typosquatting safeguard) listing a package's hex metadata before adding it. The panel builder in Igniter.Project.Deps wrote publisher-controlled fields (meta.description, owner usernames, requirement names, version) to the terminal with only newlines stripped. A malicious or typosquatted package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns) in its metadata to overwrite the panel, forging trusted author names and download counts while concealing the real ones, so a developer relying on the panel to vet the package is deceived into approving a malicious dependency.
This issue affects igniter: from 0.8.1 before 0.8.4.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:44 UTC
CWE
- CWE-150 - Improper Neutralization of Escape, Meta, or Control Sequences
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/igniter/security/a… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82584.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82584 | related |
| https://github.com/ash-project/igniter/commit/d49… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | igniter |
Affected:
0.8.1 , < 0.8.4
(semver)
cpe:2.3:a:ash-project:igniter:*:*:*:*:*:*:*:* |
|
| ash-project | igniter |
Affected:
d26d9b3a8348661813617606076315075d32663b , < d492b1aa33f8fb0dacc0afa41b703fb922d42816
(git)
cpe:2.3:a:ash-project:igniter:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82584",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:44:50.539017Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:44:59.110Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:igniter:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Igniter.Project.Deps\u0027"
],
"packageName": "igniter",
"packageURL": "pkg:hex/igniter",
"product": "igniter",
"programFiles": [
"lib/igniter/project/deps.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Igniter.Project.Deps\u0027:determine_dep_type_and_version!/2"
}
],
"repo": "https://github.com/ash-project/igniter",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.8.4",
"status": "affected",
"version": "0.8.1",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:igniter:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.Igniter.Project.Deps\u0027"
],
"packageName": "ash-project/igniter",
"packageURL": "pkg:github/ash-project/igniter",
"product": "igniter",
"programFiles": [
"lib/igniter/project/deps.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.Igniter.Project.Deps\u0027:determine_dep_type_and_version!/2"
}
],
"repo": "https://github.com/ash-project/igniter",
"vendor": "ash-project",
"versions": [
{
"lessThan": "d492b1aa33f8fb0dacc0afa41b703fb922d42816",
"status": "affected",
"version": "d26d9b3a8348661813617606076315075d32663b",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when a developer runs \u003ccode\u003emix igniter.install\u003c/code\u003e against an untrusted or misspelled package name in a terminal emulator that interprets ANSI escape sequences.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when a developer runs `mix igniter.install` against an untrusted or misspelled package name in a terminal emulator that interprets ANSI escape sequences."
}
],
"value": "Reachable only when a developer runs mix igniter.install against an untrusted or misspelled package name in a terminal emulator that interprets ANSI escape sequences."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:igniter:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.8.4",
"versionStartIncluding": "0.8.1",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project igniter allows a malicious package publisher to forge the \u003ccode\u003emix igniter.install\u003c/code\u003e confirmation prompt.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003emix igniter.install\u003c/code\u003e prints a confirmation panel (an anti-typosquatting safeguard) listing a package\u0027s hex metadata before adding it. The panel builder in \u003ccode\u003eIgniter.Project.Deps\u003c/code\u003e wrote publisher-controlled fields (\u003ccode\u003emeta.description\u003c/code\u003e, owner usernames, requirement names, version) to the terminal with only newlines stripped. A malicious or typosquatted package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns) in its metadata to overwrite the panel, forging trusted author names and download counts while concealing the real ones, so a developer relying on the panel to vet the package is deceived into approving a malicious dependency.\u003c/p\u003e\n\u003cp\u003eThis issue affects igniter: from 0.8.1 before 0.8.4.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project igniter allows a malicious package publisher to forge the `mix igniter.install` confirmation prompt.\n\n`mix igniter.install` prints a confirmation panel (an anti-typosquatting safeguard) listing a package\u0027s hex metadata before adding it. The panel builder in `Igniter.Project.Deps` wrote publisher-controlled fields (`meta.description`, owner usernames, requirement names, version) to the terminal with only newlines stripped. A malicious or typosquatted package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns) in its metadata to overwrite the panel, forging trusted author names and download counts while concealing the real ones, so a developer relying on the panel to vet the package is deceived into approving a malicious dependency.\n\nThis issue affects igniter: from 0.8.1 before 0.8.4."
}
],
"value": "Improper Neutralization of Escape, Meta, or Control Sequences vulnerability in ash-project igniter allows a malicious package publisher to forge the mix igniter.install confirmation prompt.\n\nmix igniter.install prints a confirmation panel (an anti-typosquatting safeguard) listing a package\u0027s hex metadata before adding it. The panel builder in Igniter.Project.Deps wrote publisher-controlled fields (meta.description, owner usernames, requirement names, version) to the terminal with only newlines stripped. A malicious or typosquatted package can embed ANSI terminal escape sequences (cursor movement, line erase, carriage returns) in its metadata to overwrite the panel, forging trusted author names and download counts while concealing the real ones, so a developer relying on the panel to vet the package is deceived into approving a malicious dependency.\n\nThis issue affects igniter: from 0.8.1 before 0.8.4."
}
],
"impacts": [
{
"capecId": "CAPEC-93",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-93 Log Injection-Tampering-Forging"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 2.3,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "PASSIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-150",
"description": "CWE-150 Improper Neutralization of Escape, Meta, or Control Sequences",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:54:48.222Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/igniter/security/advisories/GHSA-cj7w-j579-gc42"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82584.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82584"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/igniter/commit/d492b1aa33f8fb0dacc0afa41b703fb922d42816"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Terminal escape sequence injection in the mix igniter.install confirmation prompt via package metadata"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82584",
"datePublished": "2026-09-07T22:54:48.222Z",
"dateReserved": "2026-09-07T21:00:01.988Z",
"dateUpdated": "2026-09-08T14:44:59.110Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82586 (GCVE-0-2026-82586)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:34 – Updated: 2026-09-08 14:44
VLAI
EPSS
VEX
Title
AshLua read operation aggregate bypasses the exposed-field allow-list, exposing private attributes
Summary
Improper Protection of Alternate Path vulnerability in ash-project ash_lua allows a user-supplied Lua script to read attributes that are not on the exposed-field allow-list.
AshLua exposes Ash resources to Lua scripts, gated by a manifest declaring which fields are exposed. The read action's operation aggregate path in AshLua.Runtime took the field name straight from the Lua call and resolved it with only String.to_existing_atom and Ash.Query.Aggregate.new!, neither of which consults the exposed-field allow-list the normal fields path enforces. A script can therefore read the value of any attribute of any record the actor may read, including private sensitive?: true columns, via resource.read({ operation = {"list", "hashed_password"} }); min and max give a value oracle. Anyone able to submit or influence a Lua script can reach this.
This issue affects ash_lua: from 0.1.0 before 0.2.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:44 UTC
CWE
- CWE-424 - Improper Protection of Alternate Path
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_lua/security/a… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82586.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82586 | related |
| https://github.com/ash-project/ash_lua/commit/c0d… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_lua |
Affected:
0.1.0 , < 0.2.1
(semver)
cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:* |
|
| ash-project | ash_lua |
Affected:
8675e47cca81f36594083a7e63379bac9e123e72 , < c0dfcd9494766d548178c37df0bd01cff378e1c7
(git)
cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82586",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:44:32.288129Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:44:37.935Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshLua.Runtime\u0027"
],
"packageName": "ash_lua",
"packageURL": "pkg:hex/ash_lua",
"product": "ash_lua",
"programFiles": [
"lib/ash_lua/runtime.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshLua.Runtime\u0027:eval!/2"
}
],
"repo": "https://github.com/ash-project/ash_lua",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.2.1",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshLua.Runtime\u0027"
],
"packageName": "ash-project/ash_lua",
"packageURL": "pkg:github/ash-project/ash_lua",
"product": "ash_lua",
"programFiles": [
"lib/ash_lua/runtime.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshLua.Runtime\u0027:eval!/2"
}
],
"repo": "https://github.com/ash-project/ash_lua",
"vendor": "ash-project",
"versions": [
{
"lessThan": "c0dfcd9494766d548178c37df0bd01cff378e1c7",
"status": "affected",
"version": "8675e47cca81f36594083a7e63379bac9e123e72",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when an application exposes AshLua scripting (the \u003ccode\u003eAshLua.Resource\u003c/code\u003e / \u003ccode\u003eAshLua.Domain\u003c/code\u003e extensions) to callers who can submit or influence Lua scripts, and the exposed resource has attributes that are not on the exposed-field surface.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when an application exposes AshLua scripting (the `AshLua.Resource` / `AshLua.Domain` extensions) to callers who can submit or influence Lua scripts, and the exposed resource has attributes that are not on the exposed-field surface."
}
],
"value": "Reachable only when an application exposes AshLua scripting (the AshLua.Resource / AshLua.Domain extensions) to callers who can submit or influence Lua scripts, and the exposed resource has attributes that are not on the exposed-field surface."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_lua:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.2.1",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Protection of Alternate Path vulnerability in ash-project ash_lua allows a user-supplied Lua script to read attributes that are not on the exposed-field allow-list.\u003c/p\u003e\n\u003cp\u003eAshLua exposes Ash resources to Lua scripts, gated by a manifest declaring which fields are exposed. The \u003ccode\u003eread\u003c/code\u003e action\u0027s \u003ccode\u003eoperation\u003c/code\u003e aggregate path in \u003ccode\u003eAshLua.Runtime\u003c/code\u003e took the field name straight from the Lua call and resolved it with only \u003ccode\u003eString.to_existing_atom\u003c/code\u003e and \u003ccode\u003eAsh.Query.Aggregate.new!\u003c/code\u003e, neither of which consults the exposed-field allow-list the normal \u003ccode\u003efields\u003c/code\u003e path enforces. A script can therefore read the value of any attribute of any record the actor may read, including private \u003ccode\u003esensitive?: true\u003c/code\u003e columns, via \u003ccode\u003eresource.read({ operation = {\"list\", \"hashed_password\"} })\u003c/code\u003e; \u003ccode\u003emin\u003c/code\u003e and \u003ccode\u003emax\u003c/code\u003e give a value oracle. Anyone able to submit or influence a Lua script can reach this.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_lua: from 0.1.0 before 0.2.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Protection of Alternate Path vulnerability in ash-project ash_lua allows a user-supplied Lua script to read attributes that are not on the exposed-field allow-list.\n\nAshLua exposes Ash resources to Lua scripts, gated by a manifest declaring which fields are exposed. The `read` action\u0027s `operation` aggregate path in `AshLua.Runtime` took the field name straight from the Lua call and resolved it with only `String.to_existing_atom` and `Ash.Query.Aggregate.new!`, neither of which consults the exposed-field allow-list the normal `fields` path enforces. A script can therefore read the value of any attribute of any record the actor may read, including private `sensitive?: true` columns, via `resource.read({ operation = {\"list\", \"hashed_password\"} })`; `min` and `max` give a value oracle. Anyone able to submit or influence a Lua script can reach this.\n\nThis issue affects ash_lua: from 0.1.0 before 0.2.1."
}
],
"value": "Improper Protection of Alternate Path vulnerability in ash-project ash_lua allows a user-supplied Lua script to read attributes that are not on the exposed-field allow-list.\n\nAshLua exposes Ash resources to Lua scripts, gated by a manifest declaring which fields are exposed. The read action\u0027s operation aggregate path in AshLua.Runtime took the field name straight from the Lua call and resolved it with only String.to_existing_atom and Ash.Query.Aggregate.new!, neither of which consults the exposed-field allow-list the normal fields path enforces. A script can therefore read the value of any attribute of any record the actor may read, including private sensitive?: true columns, via resource.read({ operation = {\"list\", \"hashed_password\"} }); min and max give a value oracle. Anyone able to submit or influence a Lua script can reach this.\n\nThis issue affects ash_lua: from 0.1.0 before 0.2.1."
}
],
"impacts": [
{
"capecId": "CAPEC-554",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-554 Functionality Bypass"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-424",
"description": "CWE-424 Improper Protection of Alternate Path",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:34:14.837Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_lua/security/advisories/GHSA-37jv-wc37-fhcw"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82586.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82586"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_lua/commit/c0dfcd9494766d548178c37df0bd01cff378e1c7"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "AshLua read operation aggregate bypasses the exposed-field allow-list, exposing private attributes"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82586",
"datePublished": "2026-09-07T22:34:14.837Z",
"dateReserved": "2026-09-07T19:30:01.631Z",
"dateUpdated": "2026-09-08T14:44:37.935Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-81638 (GCVE-0-2026-81638)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:33 – Updated: 2026-09-08 14:44
VLAI
EPSS
VEX
Title
Non-canonical ULID spellings are accepted and alias to the same record in ash_double_entry
Summary
Improper Handling of Alternate Encoding vulnerability in ash-project ash_double_entry allows an attacker to submit several distinct string spellings of the same identifier.
AshDoubleEntry.ULID renders a 128-bit ULID as 26 Crockford base-32 characters, but the first character encodes only 3 bits, so canonical values are 0 to 7. decode/1 in lib/ulid.ex masks the first character to its low 3 bits and valid?/1 accepts all 32 characters in that position, so 0..., 8..., G... and R... decode to the identical 16-byte value and resolve to the same row. When the type is exposed as a public ID over an HTTP or API boundary, an attacker-supplied ID can be spelled differently from the record it actually reads or writes, desynchronizing or bypassing string-level checks such as idempotency and deduplication keys, deny-lists, audit correlation, or signatures computed over the submitted ID.
This issue affects ash_double_entry: from 0.1.0 before 1.0.19.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:44 UTC
CWE
- CWE-173 - Improper Handling of Alternate Encoding
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_double_entry/s… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-81638.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-81638 | related |
| https://github.com/ash-project/ash_double_entry/c… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_double_entry |
Affected:
0.1.0 , < 1.0.19
(semver)
cpe:2.3:a:ash-project:ash_double_entry:*:*:*:*:*:*:*:* |
|
| ash-project | ash_double_entry |
Affected:
1e5f7ce8ff25f519c904731a29eb1258324e561a , < d3e688d300a581ae214b3ca7d95ef4de63fbb050
(git)
cpe:2.3:a:ash-project:ash_double_entry:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-81638",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:44:11.859893Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:44:19.138Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_double_entry:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshDoubleEntry.ULID\u0027"
],
"packageName": "ash_double_entry",
"packageURL": "pkg:hex/ash_double_entry",
"product": "ash_double_entry",
"programFiles": [
"lib/ulid.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshDoubleEntry.ULID\u0027:cast_input/2"
},
{
"name": "\u0027Elixir.AshDoubleEntry.ULID\u0027:dump_to_native/2"
}
],
"repo": "https://github.com/ash-project/ash_double_entry",
"vendor": "ash-project",
"versions": [
{
"lessThan": "1.0.19",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_double_entry:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshDoubleEntry.ULID\u0027"
],
"packageName": "ash-project/ash_double_entry",
"packageURL": "pkg:github/ash-project/ash_double_entry",
"product": "ash_double_entry",
"programFiles": [
"lib/ulid.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshDoubleEntry.ULID\u0027:cast_input/2"
},
{
"name": "\u0027Elixir.AshDoubleEntry.ULID\u0027:dump_to_native/2"
}
],
"repo": "https://github.com/ash-project/ash_double_entry",
"vendor": "ash-project",
"versions": [
{
"lessThan": "d3e688d300a581ae214b3ca7d95ef4de63fbb050",
"status": "affected",
"version": "1e5f7ce8ff25f519c904731a29eb1258324e561a",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when an application exposes \u003ccode\u003eAshDoubleEntry.ULID\u003c/code\u003e as a public identifier over an HTTP or API boundary and performs string-level checks on the submitted ID (idempotency or deduplication keys, deny-lists, audit correlation, or signatures) rather than treating the value as opaque.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when an application exposes `AshDoubleEntry.ULID` as a public identifier over an HTTP or API boundary and performs string-level checks on the submitted ID (idempotency or deduplication keys, deny-lists, audit correlation, or signatures) rather than treating the value as opaque."
}
],
"value": "Reachable only when an application exposes AshDoubleEntry.ULID as a public identifier over an HTTP or API boundary and performs string-level checks on the submitted ID (idempotency or deduplication keys, deny-lists, audit correlation, or signatures) rather than treating the value as opaque."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_double_entry:*:*:*:*:*:*:*:*",
"versionEndExcluding": "1.0.19",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Handling of Alternate Encoding vulnerability in ash-project ash_double_entry allows an attacker to submit several distinct string spellings of the same identifier.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eAshDoubleEntry.ULID\u003c/code\u003e renders a 128-bit ULID as 26 Crockford base-32 characters, but the first character encodes only 3 bits, so canonical values are \u003ccode\u003e0\u003c/code\u003e to \u003ccode\u003e7\u003c/code\u003e. \u003ccode\u003edecode/1\u003c/code\u003e in \u003ccode\u003elib/ulid.ex\u003c/code\u003e masks the first character to its low 3 bits and \u003ccode\u003evalid?/1\u003c/code\u003e accepts all 32 characters in that position, so \u003ccode\u003e0...\u003c/code\u003e, \u003ccode\u003e8...\u003c/code\u003e, \u003ccode\u003eG...\u003c/code\u003e and \u003ccode\u003eR...\u003c/code\u003e decode to the identical 16-byte value and resolve to the same row. When the type is exposed as a public ID over an HTTP or API boundary, an attacker-supplied ID can be spelled differently from the record it actually reads or writes, desynchronizing or bypassing string-level checks such as idempotency and deduplication keys, deny-lists, audit correlation, or signatures computed over the submitted ID.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_double_entry: from 0.1.0 before 1.0.19.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Handling of Alternate Encoding vulnerability in ash-project ash_double_entry allows an attacker to submit several distinct string spellings of the same identifier.\n\n`AshDoubleEntry.ULID` renders a 128-bit ULID as 26 Crockford base-32 characters, but the first character encodes only 3 bits, so canonical values are `0` to `7`. `decode/1` in `lib/ulid.ex` masks the first character to its low 3 bits and `valid?/1` accepts all 32 characters in that position, so `0...`, `8...`, `G...` and `R...` decode to the identical 16-byte value and resolve to the same row. When the type is exposed as a public ID over an HTTP or API boundary, an attacker-supplied ID can be spelled differently from the record it actually reads or writes, desynchronizing or bypassing string-level checks such as idempotency and deduplication keys, deny-lists, audit correlation, or signatures computed over the submitted ID.\n\nThis issue affects ash_double_entry: from 0.1.0 before 1.0.19."
}
],
"value": "Improper Handling of Alternate Encoding vulnerability in ash-project ash_double_entry allows an attacker to submit several distinct string spellings of the same identifier.\n\nAshDoubleEntry.ULID renders a 128-bit ULID as 26 Crockford base-32 characters, but the first character encodes only 3 bits, so canonical values are 0 to 7. decode/1 in lib/ulid.ex masks the first character to its low 3 bits and valid?/1 accepts all 32 characters in that position, so 0..., 8..., G... and R... decode to the identical 16-byte value and resolve to the same row. When the type is exposed as a public ID over an HTTP or API boundary, an attacker-supplied ID can be spelled differently from the record it actually reads or writes, desynchronizing or bypassing string-level checks such as idempotency and deduplication keys, deny-lists, audit correlation, or signatures computed over the submitted ID.\n\nThis issue affects ash_double_entry: from 0.1.0 before 1.0.19."
}
],
"impacts": [
{
"capecId": "CAPEC-267",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-267 Leverage Alternate Encoding"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 2.1,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-173",
"description": "CWE-173 Improper Handling of Alternate Encoding",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:33:29.297Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_double_entry/security/advisories/GHSA-qxp2-vgp9-268q"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-81638.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-81638"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_double_entry/commit/d3e688d300a581ae214b3ca7d95ef4de63fbb050"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Non-canonical ULID spellings are accepted and alias to the same record in ash_double_entry"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-81638",
"datePublished": "2026-09-07T22:33:29.297Z",
"dateReserved": "2026-09-07T19:30:01.624Z",
"dateUpdated": "2026-09-08T14:44:19.138Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82758 (GCVE-0-2026-82758)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:32 – Updated: 2026-09-08 14:41
VLAI
EPSS
VEX
Title
ash_authentication_oauth2_server treats an empty resolved secret as valid, opening the gated Dynamic Client Registration endpoint
Summary
Improper Authentication vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to register OAuth clients even when Dynamic Client Registration is gated by an initial access token.
resolve_secret/3 in AshAuthentication.Oauth2Server (reached through __resolve_secret__!) treated any return other than {:ok, _} or :error from a configured {module, function, args} or 2-arity-function secret provider as a valid secret, wrapping nil, false, or "" as {:ok, value}. When the initial_access_token resolves to such an empty value, POST /oauth/register compares the presented bearer token against it and the comparison passes with no token supplied, so registration is open although it was configured closed. The same fail-open affected other resolved secrets such as signing_secret.
This issue affects ash_authentication_oauth2_server: from 0.1.0 before 0.3.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:40 UTC
CWE
- CWE-287 - Improper Authentication
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_authentication… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82758.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82758 | related |
| https://github.com/ash-project/ash_authentication… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_authentication_oauth2_server |
Affected:
0.1.0 , < 0.3.1
(semver)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
|
| ash-project | ash_authentication_oauth2_server |
Affected:
855b578037c5ded18e8a6e60f42e56bde4905fae , < 30a87101871775d27d79f9ad6f29eafa4779e118
(git)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82758",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:40:53.437993Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:41:06.227Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Oauth2Server\u0027"
],
"packageName": "ash_authentication_oauth2_server",
"packageURL": "pkg:hex/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication/oauth2_server.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server\u0027:__resolve_secret__!/3"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.3.1",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Oauth2Server\u0027"
],
"packageName": "ash-project/ash_authentication_oauth2_server",
"packageURL": "pkg:github/ash-project/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication/oauth2_server.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server\u0027:__resolve_secret__!/3"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "30a87101871775d27d79f9ad6f29eafa4779e118",
"status": "affected",
"version": "855b578037c5ded18e8a6e60f42e56bde4905fae",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when the server configures an \u003ccode\u003einitial_access_token\u003c/code\u003e (so Dynamic Client Registration is meant to require one) and the configured secret provider returns an empty value (\u003ccode\u003enil\u003c/code\u003e, \u003ccode\u003efalse\u003c/code\u003e, or \u003ccode\u003e\"\"\u003c/code\u003e) or an \u003ccode\u003e{:error, _}\u003c/code\u003e for it, rather than a non-empty binary.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when the server configures an `initial_access_token` (so Dynamic Client Registration is meant to require one) and the configured secret provider returns an empty value (`nil`, `false`, or `\"\"`) or an `{:error, _}` for it, rather than a non-empty binary."
}
],
"value": "Reachable only when the server configures an initial_access_token (so Dynamic Client Registration is meant to require one) and the configured secret provider returns an empty value (nil, false, or \"\") or an {:error, _} for it, rather than a non-empty binary."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.3.1",
"versionStartIncluding": "0.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Authentication vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to register OAuth clients even when Dynamic Client Registration is gated by an initial access token.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eresolve_secret/3\u003c/code\u003e in \u003ccode\u003eAshAuthentication.Oauth2Server\u003c/code\u003e (reached through \u003ccode\u003e__resolve_secret__!\u003c/code\u003e) treated any return other than \u003ccode\u003e{:ok, _}\u003c/code\u003e or \u003ccode\u003e:error\u003c/code\u003e from a configured \u003ccode\u003e{module, function, args}\u003c/code\u003e or 2-arity-function secret provider as a valid secret, wrapping \u003ccode\u003enil\u003c/code\u003e, \u003ccode\u003efalse\u003c/code\u003e, or \u003ccode\u003e\"\"\u003c/code\u003e as \u003ccode\u003e{:ok, value}\u003c/code\u003e. When the \u003ccode\u003einitial_access_token\u003c/code\u003e resolves to such an empty value, \u003ccode\u003ePOST /oauth/register\u003c/code\u003e compares the presented bearer token against it and the comparison passes with no token supplied, so registration is open although it was configured closed. The same fail-open affected other resolved secrets such as \u003ccode\u003esigning_secret\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication_oauth2_server: from 0.1.0 before 0.3.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Authentication vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to register OAuth clients even when Dynamic Client Registration is gated by an initial access token.\n\n`resolve_secret/3` in `AshAuthentication.Oauth2Server` (reached through `__resolve_secret__!`) treated any return other than `{:ok, _}` or `:error` from a configured `{module, function, args}` or 2-arity-function secret provider as a valid secret, wrapping `nil`, `false`, or `\"\"` as `{:ok, value}`. When the `initial_access_token` resolves to such an empty value, `POST /oauth/register` compares the presented bearer token against it and the comparison passes with no token supplied, so registration is open although it was configured closed. The same fail-open affected other resolved secrets such as `signing_secret`.\n\nThis issue affects ash_authentication_oauth2_server: from 0.1.0 before 0.3.1."
}
],
"value": "Improper Authentication vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to register OAuth clients even when Dynamic Client Registration is gated by an initial access token.\n\nresolve_secret/3 in AshAuthentication.Oauth2Server (reached through __resolve_secret__!) treated any return other than {:ok, _} or :error from a configured {module, function, args} or 2-arity-function secret provider as a valid secret, wrapping nil, false, or \"\" as {:ok, value}. When the initial_access_token resolves to such an empty value, POST /oauth/register compares the presented bearer token against it and the comparison passes with no token supplied, so registration is open although it was configured closed. The same fail-open affected other resolved secrets such as signing_secret.\n\nThis issue affects ash_authentication_oauth2_server: from 0.1.0 before 0.3.1."
}
],
"impacts": [
{
"capecId": "CAPEC-115",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-115 Authentication Bypass"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-287",
"description": "CWE-287 Improper Authentication",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:32:17.027Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/security/advisories/GHSA-fxc6-vp68-87pw"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82758.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82758"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/commit/30a87101871775d27d79f9ad6f29eafa4779e118"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "ash_authentication_oauth2_server treats an empty resolved secret as valid, opening the gated Dynamic Client Registration endpoint"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82758",
"datePublished": "2026-09-07T22:32:17.027Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-08T14:41:06.227Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82757 (GCVE-0-2026-82757)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:31 – Updated: 2026-09-08 14:43
VLAI
EPSS
VEX
Title
ash_authentication_oauth2_server CIMD fetcher classifies IPv4-in-IPv6 and site-local addresses as public, allowing SSRF
Summary
Server-Side Request Forgery (SSRF) vulnerability in ash-project ash_authentication_oauth2_server allows an attacker who controls a client metadata URL and its DNS to make the server connect to internal or loopback addresses.
public_ip?/1 in AshAuthentication.Oauth2Server.CIMD.ReqFetcher enforces the outbound policy for CIMD metadata fetches. It classified several address forms as publicly routable that are not: IPv4-compatible ::/96 (for example ::127.0.0.1), SIIT IPv4-translated ::ffff:0:0:0/96, and deprecated site-local fec0::/10. A returned AAAA record in one of these ranges passed the policy, so a fetch pinned to that address reached space the policy was meant to block.
This issue affects ash_authentication_oauth2_server: from 0.3.0 before 0.3.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:43 UTC
CWE
- CWE-918 - Server-Side Request Forgery (SSRF)
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_authentication… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82757.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82757 | related |
| https://github.com/ash-project/ash_authentication… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_authentication_oauth2_server |
Affected:
0.3.0 , < 0.3.1
(semver)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
|
| ash-project | ash_authentication_oauth2_server |
Affected:
e713a9ba816761140c226e2ca55b75c0b93f5984 , < 268b591261a3473ab9b87272963e4dd2fd99d972
(git)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82757",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:43:50.818031Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:43:57.511Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027"
],
"packageName": "ash_authentication_oauth2_server",
"packageURL": "pkg:hex/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication/oauth2_server/cimd/req_fetcher.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027:public_ip?/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027:fetch/2"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.3.1",
"status": "affected",
"version": "0.3.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027"
],
"packageName": "ash-project/ash_authentication_oauth2_server",
"packageURL": "pkg:github/ash-project/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication/oauth2_server/cimd/req_fetcher.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027:public_ip?/1"
},
{
"name": "\u0027Elixir.AshAuthentication.Oauth2Server.CIMD.ReqFetcher\u0027:fetch/2"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "268b591261a3473ab9b87272963e4dd2fd99d972",
"status": "affected",
"version": "e713a9ba816761140c226e2ca55b75c0b93f5984",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only when Client ID Metadata Documents are enabled (\u003ccode\u003ecimd_enabled?: true\u003c/code\u003e), so the authorize endpoint fetches attacker-suppliable metadata URLs, and an internal or loopback target resolves to one of the affected IPv6 address forms.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only when Client ID Metadata Documents are enabled (`cimd_enabled?: true`), so the authorize endpoint fetches attacker-suppliable metadata URLs, and an internal or loopback target resolves to one of the affected IPv6 address forms."
}
],
"value": "Reachable only when Client ID Metadata Documents are enabled (cimd_enabled?: true), so the authorize endpoint fetches attacker-suppliable metadata URLs, and an internal or loopback target resolves to one of the affected IPv6 address forms."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.3.1",
"versionStartIncluding": "0.3.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eServer-Side Request Forgery (SSRF) vulnerability in ash-project ash_authentication_oauth2_server allows an attacker who controls a client metadata URL and its DNS to make the server connect to internal or loopback addresses.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003epublic_ip?/1\u003c/code\u003e in \u003ccode\u003eAshAuthentication.Oauth2Server.CIMD.ReqFetcher\u003c/code\u003e enforces the outbound policy for CIMD metadata fetches. It classified several address forms as publicly routable that are not: IPv4-compatible \u003ccode\u003e::/96\u003c/code\u003e (for example \u003ccode\u003e::127.0.0.1\u003c/code\u003e), SIIT IPv4-translated \u003ccode\u003e::ffff:0:0:0/96\u003c/code\u003e, and deprecated site-local \u003ccode\u003efec0::/10\u003c/code\u003e. A returned AAAA record in one of these ranges passed the policy, so a fetch pinned to that address reached space the policy was meant to block.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication_oauth2_server: from 0.3.0 before 0.3.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Server-Side Request Forgery (SSRF) vulnerability in ash-project ash_authentication_oauth2_server allows an attacker who controls a client metadata URL and its DNS to make the server connect to internal or loopback addresses.\n\n`public_ip?/1` in `AshAuthentication.Oauth2Server.CIMD.ReqFetcher` enforces the outbound policy for CIMD metadata fetches. It classified several address forms as publicly routable that are not: IPv4-compatible `::/96` (for example `::127.0.0.1`), SIIT IPv4-translated `::ffff:0:0:0/96`, and deprecated site-local `fec0::/10`. A returned AAAA record in one of these ranges passed the policy, so a fetch pinned to that address reached space the policy was meant to block.\n\nThis issue affects ash_authentication_oauth2_server: from 0.3.0 before 0.3.1."
}
],
"value": "Server-Side Request Forgery (SSRF) vulnerability in ash-project ash_authentication_oauth2_server allows an attacker who controls a client metadata URL and its DNS to make the server connect to internal or loopback addresses.\n\npublic_ip?/1 in AshAuthentication.Oauth2Server.CIMD.ReqFetcher enforces the outbound policy for CIMD metadata fetches. It classified several address forms as publicly routable that are not: IPv4-compatible ::/96 (for example ::127.0.0.1), SIIT IPv4-translated ::ffff:0:0:0/96, and deprecated site-local fec0::/10. A returned AAAA record in one of these ranges passed the policy, so a fetch pinned to that address reached space the policy was meant to block.\n\nThis issue affects ash_authentication_oauth2_server: from 0.3.0 before 0.3.1."
}
],
"impacts": [
{
"capecId": "CAPEC-664",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-664 Server Side Request Forgery"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "LOW",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-918",
"description": "CWE-918 Server-Side Request Forgery (SSRF)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:31:34.656Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/security/advisories/GHSA-wprp-8gvj-p6cv"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82757.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82757"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/commit/268b591261a3473ab9b87272963e4dd2fd99d972"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "ash_authentication_oauth2_server CIMD fetcher classifies IPv4-in-IPv6 and site-local addresses as public, allowing SSRF"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82757",
"datePublished": "2026-09-07T22:31:34.656Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-08T14:43:57.511Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-82756 (GCVE-0-2026-82756)
Vulnerability from cvelistv5 – Published: 2026-09-07 22:30 – Updated: 2026-09-08 14:43
VLAI
EPSS
VEX
Title
ash_authentication_oauth2_server interpolates a tenant-derived value into the WWW-Authenticate challenge without escaping, allowing header parameter injection
Summary
Improper Encoding or Escaping of Output vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to inject arbitrary authentication parameters into the WWW-Authenticate challenge header.
BearerPlug and RequireScopePlug built the Bearer resource_metadata="..." challenge by interpolating a resource_metadata URL derived from the request tenant directly into the quoted value. In a multi-tenant application that sets the Ash tenant from request-controlled data (a subdomain, the Host, a path segment, or a header), a tenant containing a " closes the quoted value and appends attacker-chosen auth-params, including a second resource_metadata URL pointing at an attacker-controlled authorization server that spec-following clients follow. Carriage returns and line feeds are rejected by Plug, so this is parameter injection within one header, not response splitting.
This issue affects ash_authentication_oauth2_server: from 0.1.3 before 0.3.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-08 14:43 UTC
CWE
- CWE-116 - Improper Encoding or Escaping of Output
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/ash-project/ash_authentication… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-82756.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-82756 | related |
| https://github.com/ash-project/ash_authentication… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| ash-project | ash_authentication_oauth2_server |
Affected:
0.1.3 , < 0.3.1
(semver)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
|
| ash-project | ash_authentication_oauth2_server |
Affected:
99de0a1cacb5ef667c4533278b7c81ca98c00231 , < 09f97476715da031b136eaec7b2cda2363ad8149
(git)
cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-82756",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-08T14:43:23.093058Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T14:43:33.571Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.BearerPlug\u0027",
"\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.RequireScopePlug\u0027"
],
"packageName": "ash_authentication_oauth2_server",
"packageURL": "pkg:hex/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication_phoenix/oauth2_server/bearer_plug.ex",
"lib/ash_authentication_phoenix/oauth2_server/require_scope_plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.BearerPlug\u0027:call/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.RequireScopePlug\u0027:call/2"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "0.3.1",
"status": "affected",
"version": "0.1.3",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.BearerPlug\u0027",
"\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.RequireScopePlug\u0027"
],
"packageName": "ash-project/ash_authentication_oauth2_server",
"packageURL": "pkg:github/ash-project/ash_authentication_oauth2_server",
"product": "ash_authentication_oauth2_server",
"programFiles": [
"lib/ash_authentication_phoenix/oauth2_server/bearer_plug.ex",
"lib/ash_authentication_phoenix/oauth2_server/require_scope_plug.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.BearerPlug\u0027:call/2"
},
{
"name": "\u0027Elixir.AshAuthentication.Phoenix.Oauth2Server.RequireScopePlug\u0027:call/2"
}
],
"repo": "https://github.com/ash-project/ash_authentication_oauth2_server",
"vendor": "ash-project",
"versions": [
{
"lessThan": "09f97476715da031b136eaec7b2cda2363ad8149",
"status": "affected",
"version": "99de0a1cacb5ef667c4533278b7c81ca98c00231",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReachable only in a multi-tenant application that derives the Ash tenant from request-controlled input (subdomain, \u003ccode\u003eHost\u003c/code\u003e, path, or header) and uses \u003ccode\u003eBearerPlug\u003c/code\u003e or \u003ccode\u003eRequireScopePlug\u003c/code\u003e; the tenant reaches the challenge through the server\u0027s tenant-aware \u003ccode\u003eresource_url\u003c/code\u003e.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reachable only in a multi-tenant application that derives the Ash tenant from request-controlled input (subdomain, `Host`, path, or header) and uses `BearerPlug` or `RequireScopePlug`; the tenant reaches the challenge through the server\u0027s tenant-aware `resource_url`."
}
],
"value": "Reachable only in a multi-tenant application that derives the Ash tenant from request-controlled input (subdomain, Host, path, or header) and uses BearerPlug or RequireScopePlug; the tenant reaches the challenge through the server\u0027s tenant-aware resource_url."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:ash-project:ash_authentication_oauth2_server:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.3.1",
"versionStartIncluding": "0.1.3",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "reporter",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Zach Daniel / Ash Project"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Encoding or Escaping of Output vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to inject arbitrary authentication parameters into the \u003ccode\u003eWWW-Authenticate\u003c/code\u003e challenge header.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eBearerPlug\u003c/code\u003e and \u003ccode\u003eRequireScopePlug\u003c/code\u003e built the \u003ccode\u003eBearer resource_metadata=\"...\"\u003c/code\u003e challenge by interpolating a \u003ccode\u003eresource_metadata\u003c/code\u003e URL derived from the request tenant directly into the quoted value. In a multi-tenant application that sets the Ash tenant from request-controlled data (a subdomain, the \u003ccode\u003eHost\u003c/code\u003e, a path segment, or a header), a tenant containing a \u003ccode\u003e\"\u003c/code\u003e closes the quoted value and appends attacker-chosen auth-params, including a second \u003ccode\u003eresource_metadata\u003c/code\u003e URL pointing at an attacker-controlled authorization server that spec-following clients follow. Carriage returns and line feeds are rejected by Plug, so this is parameter injection within one header, not response splitting.\u003c/p\u003e\n\u003cp\u003eThis issue affects ash_authentication_oauth2_server: from 0.1.3 before 0.3.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Encoding or Escaping of Output vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to inject arbitrary authentication parameters into the `WWW-Authenticate` challenge header.\n\n`BearerPlug` and `RequireScopePlug` built the `Bearer resource_metadata=\"...\"` challenge by interpolating a `resource_metadata` URL derived from the request tenant directly into the quoted value. In a multi-tenant application that sets the Ash tenant from request-controlled data (a subdomain, the `Host`, a path segment, or a header), a tenant containing a `\"` closes the quoted value and appends attacker-chosen auth-params, including a second `resource_metadata` URL pointing at an attacker-controlled authorization server that spec-following clients follow. Carriage returns and line feeds are rejected by Plug, so this is parameter injection within one header, not response splitting.\n\nThis issue affects ash_authentication_oauth2_server: from 0.1.3 before 0.3.1."
}
],
"value": "Improper Encoding or Escaping of Output vulnerability in ash-project ash_authentication_oauth2_server allows an unauthenticated attacker to inject arbitrary authentication parameters into the WWW-Authenticate challenge header.\n\nBearerPlug and RequireScopePlug built the Bearer resource_metadata=\"...\" challenge by interpolating a resource_metadata URL derived from the request tenant directly into the quoted value. In a multi-tenant application that sets the Ash tenant from request-controlled data (a subdomain, the Host, a path segment, or a header), a tenant containing a \" closes the quoted value and appends attacker-chosen auth-params, including a second resource_metadata URL pointing at an attacker-controlled authorization server that spec-following clients follow. Carriage returns and line feeds are rejected by Plug, so this is parameter injection within one header, not response splitting.\n\nThis issue affects ash_authentication_oauth2_server: from 0.1.3 before 0.3.1."
}
],
"impacts": [
{
"capecId": "CAPEC-153",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-153 Input Data Manipulation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "LOW",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-116",
"description": "CWE-116 Improper Encoding or Escaping of Output",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-07T22:30:55.280Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/security/advisories/GHSA-2h3v-83jg-2qmm"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-82756.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-82756"
},
{
"tags": [
"patch"
],
"url": "https://github.com/ash-project/ash_authentication_oauth2_server/commit/09f97476715da031b136eaec7b2cda2363ad8149"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "ash_authentication_oauth2_server interpolates a tenant-derived value into the WWW-Authenticate challenge without escaping, allowing header parameter injection"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-82756",
"datePublished": "2026-09-07T22:30:55.280Z",
"dateReserved": "2026-08-31T01:00:10.817Z",
"dateUpdated": "2026-09-08T14:43:33.571Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}