GHSA-28F5-38XR-JH2W

Vulnerability from github – Published: 2026-07-28 14:26 – Updated: 2026-07-28 14:26
VLAI
Summary
java-client Allows Network Pivot via Unvalidated directConnect Redirect in AppiumCommandExecutor
Details

Summary

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 calls overrideServerUrl(newUrl) without validating host/IP.
  • DirectConnect.java: getUrl() constructs protocol://host:port/path with 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:

1

Screenshot 2 — Java client processing response from attacker host:

2

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.

poc_appium_directconnect.zip

Show details on source website

{
  "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"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

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.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…