CVE-2026-59185: Identrail Cross-tenant IDOR Client-supplied GitHub App Installation_id Is Vulnerability
HIGHCVE-2026-59185 is a HIGH (CVSS 8.5) client-supplied github app installation_id is vulnerability (CWE-639: Authorization Bypass Through User-Controlled Key) affecting Identrail Cross-tenant IDOR libraries in the Go ecosystem. The issue involves client-supplied github app installation_id is bound to the caller's workspace without ownership verification. Remediation is available by upgrading affected packages to version 1.0.2.
CVE-2026-59185 at a Glance
Security Impact
CVSS: 8.5
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N).
How to Fix CVE-2026-59185
To remediate this vulnerability, upgrade all affected Identrail Cross-tenant IDOR dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/identrail/identrail to 1.0.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/identrail/identrail
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-59185, inspect your project dependencies for Identrail Cross-tenant IDOR:
inspect dependencies for github.com/identrail/identrail
Analyze the terminal output to locate any version of Identrail Cross-tenant IDOR in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.0.2), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-639: Authorization Bypass Through User-Controlled Key, where the system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data. In Identrail Cross-tenant IDOR, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-59185 Affected Identrail Cross-tenant IDOR Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/identrail/identrail
|
Go |
< 1.0.2
|
1.0.2
|
References
Frequently Asked Questions
What is CVE-2026-59185?
Which Identrail Cross-tenant IDOR versions are affected?
What version fixes CVE-2026-59185?
Is github.com/identrail/identrail affected?
What is the CVSS score of CVE-2026-59185?
What CWE is associated with CVE-2026-59185?
How can I check Go dependencies for CVE-2026-59185?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-cp3j-m783-3ph5",
"modified" : "2026-09-09T23:52:14Z",
"published" : "2026-09-09T23:52:14Z",
"aliases" : [ "CVE-2026-59185" ],
"summary" : "Identrail Cross-tenant IDOR: Client-supplied GitHub App installation_id is bound to the caller's workspace without ownership verification",
"details" : "## Summary\n\nidentrail's GitHub App connection-completion endpoint binds a fully client-supplied `installation_id` to the caller's workspace without verifying that the installation belongs to, or was installed by, the workspace that initiated the connect flow. identrail then mints a GitHub App installation access token for the supplied `installation_id` using the app's own JWT, so an authenticated tenant can link any other identrail customer's GitHub App installation into their own workspace and read that victim organization's private repositories.\n\n## Affected code (default-on path, no feature flag)\n\n- Route: `internal/api/router.go:3590` — `POST /v1/workspaces/:workspace_id/projects/:project_id/github/connect/complete`. `installation_id` is read from the JSON body or the attacker-controlled `X-GitHub-Installation-ID` header (`router.go:3582-3588`).\n- Service: `internal/api/github_connect.go:781` `CompleteGitHubConnection`. The `state` token IS rigorously bound to the caller's scope (`github_connect.go:818`: `if stateRecord.TenantID != scope.TenantID || stateRecord.WorkspaceID != project.WorkspaceID || stateRecord.ProjectID != project.ProjectID { ... }`), but the only check on `installation_id` is `request.InstallationID <= 0` (`:794`). The raw client value is persisted as the workspace's connection (`:840`).\n- Cross-tenant read primitive: `internal/connectors/github/repositories.go:39` `ListInstallationRepositories` → `internal/connectors/github/app.go:170` mints a token via `POST /app/installations/{installationId}/access_tokens` signed with the App JWT, succeeding for any installation where identrail's app is installed.\n\nThe feature-flagged V2 path `CompleteGitHubConnector` (`github_connect.go:447`, default off) shares the gap and is additionally weaker (matches pending connector by `state` value alone with no caller-scope re-check); a single fix should cover both.\n\n## Intent proof\n\nThe code binds `state` to `{TenantID, WorkspaceID, ProjectID}` and re-verifies it at completion (`:818`), demonstrating it understands binding is required. The asymmetry — `state` bound, `installation_id` unbound — is the missed check.\n\n## Exploitation\n\n1. Attacker is any authenticated identrail tenant; they call `StartGitHubConnection` for their own workspace and receive a `state`.\n2. Attacker calls the completion route with `{state: <their state>, installation_id: V}` where V is a victim org's identrail GitHub App installation id (installation ids are not secret — they appear in post-install redirect URLs, webhook payloads, the org's GitHub App settings, and are enumerable integers).\n3. `CompleteGitHubConnection` accepts (state matches attacker scope), `ListInstallationRepositories(V)` mints a token for V and lists the victim org's private repos, and the connection is persisted under the attacker's workspace.\n4. Attacker now reads the victim org's private repository inventory and can drive posture scans/repo reads via their own workspace.\n\nImpact: cross-tenant disclosure of another customer organization's private GitHub repositories and metadata.\n\n## Remediation\n\nBind `installation_id` with the same rigor as `state`: capture it from GitHub's signed post-install redirect (`setup_url`/`callback_url`) and pin it to the pending state at start time, and/or after minting verify the installation's `account` matches the org the initiating workspace is authorized for.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/identrail/identrail"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.0.2"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/identrail/identrail/security/advisories/GHSA-cp3j-m783-3ph5"
}, {
"type" : "WEB",
"url" : "https://github.com/identrail/identrail/commit/835e40517509d6ef5405c27fbf14f579bedff0e7"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/identrail/identrail"
}, {
"type" : "WEB",
"url" : "https://github.com/identrail/identrail/releases/tag/v1.0.2"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-639", "CWE-862" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-09-09T23:52:14Z",
"nvd_published_at" : null
}
}