GHSA-28F5-38XR-JH2W
Vulnerability from github – Published: 2026-07-28 14:26 – Updated: 2026-07-28 14:26Summary
When directConnect(true) is enabled, appium/java-client unconditionally
accepts directConnectHost, directConnectPort, and directConnectPath
from the server's NEW_SESSION response and silently redirects all subsequent
session traffic to the attacker-specified endpoint — with no allowlist,
no host validation, and no user notification.
Affected Code
AppiumCommandExecutor.java(line 196–219):setDirectConnect()builds a new URL from server-supplied fields and callsoverrideServerUrl(newUrl)without validating host/IP.DirectConnect.java:getUrl()constructsprotocol://host:port/pathwith no allowlist.
Root Cause
Only the protocol is validated (must equal "https"). The destination host and port are never checked against any allowlist or denylist.
PoC (confirmed)
A rogue server injecting directConnectHost=127.0.0.1:4443 causes the
client to silently redirect all post-session commands:
[bootstrap] POST /wd/hub/session [bootstrap] Injecting directConnect -> https://127.0.0.1:4443/wd/hub [redirect-target] HIT #1: GET /wd/hub/session/poc-session-001/source [redirect-target] HIT #2: DELETE /wd/hub/session/poc-session-001
Original source code unmodified — confirmed via git diff HEAD (empty).
Evidence Screenshots
Screenshot 1 — Rogue server capturing redirected traffic:
Screenshot 2 — Java client processing response from attacker host:
Impact
- Full interception of session traffic
- Network pivot to internal hosts (RFC-1918, 169.254.169.254)
- Cloud credential theft via IMDS endpoint
- Escalates to ~8.1 High in CI/CD environments where directConnect(true) is set in shared base configuration
Suggested Fix
Add allowlist validation before overrideServerUrl() is called, and/or
block RFC-1918/loopback/link-local destinations by default.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 10.1.0"
},
"package": {
"ecosystem": "Maven",
"name": "io.appium:java-client"
},
"ranges": [
{
"events": [
{
"introduced": "8.2.1"
},
{
"fixed": "10.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-43910"
],
"database_specific": {
"cwe_ids": [
"CWE-441",
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-28T14:26:53Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nWhen `directConnect(true)` is enabled, appium/java-client unconditionally\naccepts `directConnectHost`, `directConnectPort`, and `directConnectPath`\nfrom the server\u0027s NEW_SESSION response and silently redirects all subsequent\nsession traffic to the attacker-specified endpoint \u2014 with no allowlist,\nno host validation, and no user notification.\n\n## Affected Code\n\n- `AppiumCommandExecutor.java` (line 196\u2013219): `setDirectConnect()` builds\n a new URL from server-supplied fields and calls `overrideServerUrl(newUrl)`\n without validating host/IP.\n- `DirectConnect.java`: `getUrl()` constructs `protocol://host:port/path`\n with no allowlist.\n\n## Root Cause\n\nOnly the protocol is validated (must equal \"https\"). The destination host\nand port are never checked against any allowlist or denylist.\n\n## PoC (confirmed)\n\nA rogue server injecting `directConnectHost=127.0.0.1:4443` causes the\nclient to silently redirect all post-session commands:\n\n[bootstrap] POST /wd/hub/session\n[bootstrap] Injecting directConnect -\u003e https://127.0.0.1:4443/wd/hub\n[redirect-target] HIT #1: GET /wd/hub/session/poc-session-001/source\n[redirect-target] HIT #2: DELETE /wd/hub/session/poc-session-001\n\nOriginal source code unmodified \u2014 confirmed via `git diff HEAD` (empty).\n\n## Evidence Screenshots\n\n**Screenshot 1 \u2014 Rogue server capturing redirected traffic:**\n\n\u003cimg width=\"887\" height=\"146\" alt=\"1\" src=\"https://github.com/user-attachments/assets/cc28002c-ea20-4ac8-8336-cec632e3c842\" /\u003e\n\n**Screenshot 2 \u2014 Java client processing response from attacker host:**\n\n\u003cimg width=\"788\" height=\"130\" alt=\"2\" src=\"https://github.com/user-attachments/assets/222cbab0-0d53-45b2-847d-6aa4e3b79370\" /\u003e\n\n## Impact\n\n- Full interception of session traffic\n- Network pivot to internal hosts (RFC-1918, 169.254.169.254)\n- Cloud credential theft via IMDS endpoint\n- Escalates to ~8.1 High in CI/CD environments where directConnect(true)\n is set in shared base configuration\n\n## Suggested Fix\n\nAdd allowlist validation before `overrideServerUrl()` is called, and/or\nblock RFC-1918/loopback/link-local destinations by default.\n\n[poc_appium_directconnect.zip](https://github.com/user-attachments/files/26472525/poc_appium_directconnect.zip)",
"id": "GHSA-28f5-38xr-jh2w",
"modified": "2026-07-28T14:26:53Z",
"published": "2026-07-28T14:26:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/appium/java-client/security/advisories/GHSA-28f5-38xr-jh2w"
},
{
"type": "WEB",
"url": "https://github.com/appium/java-client/pull/2408"
},
{
"type": "WEB",
"url": "https://github.com/appium/java-client/commit/2b9cd442b9dbf56ccc6f1e83aeeb411c0ec230c9"
},
{
"type": "PACKAGE",
"url": "https://github.com/appium/java-client"
},
{
"type": "WEB",
"url": "https://github.com/appium/java-client/releases/tag/v10.1.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "java-client Allows Network Pivot via Unvalidated directConnect Redirect in AppiumCommandExecutor"
}
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.