CVE-2026-54885
Full vulnerability record from the local CVENow database.
Description
Server-Side Request Forgery vulnerability in malach-it Boruta allows an unauthenticated remote attacker to cause the OAuth/OpenID authorization server to issue outbound HTTP requests to attacker-chosen URIs, including internal services and cloud metadata endpoints. Three code paths fetch remote URIs supplied by the requester without sufficient validation of the target. Boruta.Oauth.Request.Base.fetch_unsigned_request/1 in lib/boruta/oauth/request/base.ex dereferences the OAuth request_uri parameter from the authorization request via Finch.build(:get, request_uri) |> Finch.request(OpenIDHttpClient). Boruta.Openid.parse_registration_params/2 in lib/boruta/openid.ex dereferences the jwks_uri supplied in an OpenID Connect dynamic client registration request. Boruta.Ecto.Clients.refresh_jwk_from_jwks_uri/1 in lib/boruta/adapters/ecto/clients.ex later refreshes the stored jwks_uri for an existing client. In all three paths the only validation is that the URI parses with a scheme (and one of the two request_uri clauses does not even restrict the scheme to http or https). The implementations do not require HTTPS, do not enforce a host or IP allowlist, do not reject loopback, private, link-local, or other non-public ranges after DNS resolution, do not cap response size, and do not constrain redirects. An attacker can therefore steer the server's HTTP client at arbitrary network targets reachable from the Boruta host. This issue affects boruta: from 2.3.2 before 2.3.7.
View original CVE JSON
{
"id": "CVE-2026-54885",
"sourceIdentifier": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"published": "2026-07-30T15:16:34.050",
"lastModified": "2026-10-23T22:10:00.160",
"vulnStatus": "Deferred",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "Server-Side Request Forgery vulnerability in malach-it Boruta allows an unauthenticated remote attacker to cause the OAuth/OpenID authorization server to issue outbound HTTP requests to attacker-chosen URIs, including internal services and cloud metadata endpoints.\n\nThree code paths fetch remote URIs supplied by the requester without sufficient validation of the target. Boruta.Oauth.Request.Base.fetch_unsigned_request/1 in lib/boruta/oauth/request/base.ex dereferences the OAuth request_uri parameter from the authorization request via Finch.build(:get, request_uri) |> Finch.request(OpenIDHttpClient). Boruta.Openid.parse_registration_params/2 in lib/boruta/openid.ex dereferences the jwks_uri supplied in an OpenID Connect dynamic client registration request. Boruta.Ecto.Clients.refresh_jwk_from_jwks_uri/1 in lib/boruta/adapters/ecto/clients.ex later refreshes the stored jwks_uri for an existing client. In all three paths the only validation is that the URI parses with a scheme (and one of the two request_uri clauses does not even restrict the scheme to http or https). The implementations do not require HTTPS, do not enforce a host or IP allowlist, do not reject loopback, private, link-local, or other non-public ranges after DNS resolution, do not cap response size, and do not constrain redirects. An attacker can therefore steer the server's HTTP client at arbitrary network targets reachable from the Boruta host.\n\nThis issue affects boruta: from 2.3.2 before 2.3.7."
},
{
"lang": "es",
"value": "Una vulnerabilidad de falsificación de petición del lado del servidor en malach-it Boruta permite a un atacante remoto no autenticado causar que el servidor de autorización OAuth/OpenID emita peticiones HTTP salientes a URIs elegidas por el atacante, incluyendo servicios internos y puntos finales de metadatos en la nube.\n\nTres rutas de código obtienen URIs remotas suministradas por el solicitante sin validación suficiente del objetivo. Boruta.Oauth.Request.Base.fetch_unsigned_request/1 en lib/boruta/oauth/request/base.ex desreferencia el parámetro request_uri de OAuth de la petición de autorización a través de Finch.build(:get, request_uri) |> Finch.request(OpenIDHttpClient). Boruta.Openid.parse_registration_params/2 en lib/boruta/openid.ex desreferencia la jwks_uri suministrada en una petición de registro de cliente dinámico de OpenID Connect. Boruta.Ecto.Clients.refresh_jwk_from_jwks_uri/1 en lib/boruta/adapters/ecto/clients.ex posteriormente actualiza la jwks_uri almacenada para un cliente existente. En las tres rutas, la única validación es que la URI se analiza con un esquema (y una de las dos cláusulas de request_uri ni siquiera restringe el esquema a http o https). Las implementaciones no requieren HTTPS, no aplican una lista de permitidos de host o IP, no rechazan rangos de loopback, privados, link-local u otros rangos no públicos después de la resolución DNS, no limitan el tamaño de la respuesta y no restringen las redirecciones. Un atacante puede, por lo tanto, dirigir el cliente HTTP del servidor a objetivos de red arbitrarios alcanzables desde el host de Boruta.\n\nEste problema afecta a boruta: desde 2.3.2 antes de 2.3.7."
}
],
"affected": [
{
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"affectedData": [
{
"vendor": "malach-it",
"product": "boruta",
"defaultStatus": "unaffected",
"collectionURL": "https://repo.hex.pm",
"packageName": "boruta",
"cpes": [
"cpe:2.3:a:malach-it:boruta_auth:*:*:*:*:*:*:*:*"
],
"modules": [
"'Elixir.Boruta.Oauth.Request.Base'",
"'Elixir.Boruta.Openid'",
"'Elixir.Boruta.Ecto.Clients'"
],
"programFiles": [
"lib/boruta/oauth/request/base.ex",
"lib/boruta/openid.ex",
"lib/boruta/adapters/ecto/clients.ex"
],
"programRoutines": [
{
"name": "'Elixir.Boruta.Oauth.Request.Base':fetch_unsigned_request/1"
},
{
"name": "'Elixir.Boruta.Openid':parse_registration_params/2"
},
{
"name": "'Elixir.Boruta.Ecto.Clients':refresh_jwk_from_jwks_uri/1"
}
],
"repo": "https://github.com/malach-it/boruta_auth",
"packageURL": "pkg:hex/boruta",
"versions": [
{
"version": "2.3.2",
"lessThan": "2.3.7",
"versionType": "semver",
"status": "affected"
}
]
},
{
"vendor": "malach-it",
"product": "boruta",
"defaultStatus": "unaffected",
"collectionURL": "https://github.com",
"packageName": "malach-it/boruta_auth",
"cpes": [
"cpe:2.3:a:malach-it:boruta_auth:*:*:*:*:*:*:*:*"
],
"modules": [
"'Elixir.Boruta.Oauth.Request.Base'",
"'Elixir.Boruta.Openid'",
"'Elixir.Boruta.Ecto.Clients'"
],
"programFiles": [
"lib/boruta/oauth/request/base.ex",
"lib/boruta/openid.ex",
"lib/boruta/adapters/ecto/clients.ex"
],
"programRoutines": [
{
"name": "'Elixir.Boruta.Oauth.Request.Base':fetch_unsigned_request/1"
},
{
"name": "'Elixir.Boruta.Openid':parse_registration_params/2"
},
{
"name": "'Elixir.Boruta.Ecto.Clients':refresh_jwk_from_jwks_uri/1"
}
],
"repo": "https://github.com/malach-it/boruta_auth",
"packageURL": "pkg:github/malach-it/boruta_auth",
"versions": [
{
"version": "15455b86206e0370eabd64c1856a5c996b436455",
"lessThan": "*",
"versionType": "git",
"status": "affected",
"changes": [
{
"at": "001e3dc5c259e67c6f907e98867eda4141c96d0d",
"status": "unaffected"
},
{
"at": "95fb10b78129355e475681f324c9a01ef0af2be5",
"status": "unaffected"
}
]
}
]
}
]
}
],
"metrics": {
"cvssMetricV40": [
{
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"type": "Secondary",
"cvssData": {
"version": "4.0",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"baseScore": 6.9,
"baseSeverity": "MEDIUM",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnAvailabilityImpact": "NONE",
"subConfidentialityImpact": "LOW",
"subIntegrityImpact": "LOW",
"subAvailabilityImpact": "NONE",
"exploitMaturity": "NOT_DEFINED",
"confidentialityRequirement": "NOT_DEFINED",
"integrityRequirement": "NOT_DEFINED",
"availabilityRequirement": "NOT_DEFINED",
"modifiedAttackVector": "NOT_DEFINED",
"modifiedAttackComplexity": "NOT_DEFINED",
"modifiedAttackRequirements": "NOT_DEFINED",
"modifiedPrivilegesRequired": "NOT_DEFINED",
"modifiedUserInteraction": "NOT_DEFINED",
"modifiedVulnConfidentialityImpact": "NOT_DEFINED",
"modifiedVulnIntegrityImpact": "NOT_DEFINED",
"modifiedVulnAvailabilityImpact": "NOT_DEFINED",
"modifiedSubConfidentialityImpact": "NOT_DEFINED",
"modifiedSubIntegrityImpact": "NOT_DEFINED",
"modifiedSubAvailabilityImpact": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"valueDensity": "NOT_DEFINED",
"vulnerabilityResponseEffort": "NOT_DEFINED",
"providerUrgency": "NOT_DEFINED"
}
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"timestamp": "2026-07-30T16:14:18.216537Z",
"id": "CVE-2026-54885",
"options": [
{
"exploitation": "poc"
},
{
"automatable": "no"
},
{
"technicalImpact": "partial"
}
],
"role": "CISA Coordinator",
"version": "2.0.3"
}
}
]
},
"weaknesses": [
{
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-918"
}
]
}
],
"references": [
{
"url": "https://cna.erlef.org/cves/CVE-2026-54885.html",
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
},
{
"url": "https://github.com/malach-it/boruta_auth/commit/001e3dc5c259e67c6f907e98867eda4141c96d0d",
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
},
{
"url": "https://github.com/malach-it/boruta_auth/commit/95fb10b78129355e475681f324c9a01ef0af2be5",
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
},
{
"url": "https://github.com/malach-it/boruta_auth/security/advisories/GHSA-5q9h-vf5j-fr2g",
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
},
{
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-54885",
"source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
},
{
"url": "https://github.com/malach-it/boruta_auth/security/advisories/GHSA-5q9h-vf5j-fr2g",
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"
}
]
}