NewN-Day-BenchView benchmark
winfunc
Back to Hacktivity

Status: Patched

This vulnerability has been verified as resolved and deployed.

flyctl logo
flyctlHigh2026-09-08

MCP client setup exposes Fly API tokens to other local users

Summary

A long-lived Fly bearer token was serialized into a client config created with ambient file permissions

The stream/SSE MCP setup command placed the user's reusable Fly API token in a client configuration argument list. On a normal Unix umask 022, the config could be created or replaced as mode 0644, allowing another local account to read the credential.

Root cause. runServer() appended --bearer-token to the persisted MCP proxy arguments and UpdateConfig() used ordinary file creation/rename semantics without enforcing an owner-only mode on the final file.

Remediation evidence. Fly opened PR #5192 the day after the disclosure and merged it on 8 September 2026. The exact patch writes new MCP configuration at 0600, repairs permissive existing files during replacement, and includes Unix permission regression tests.

CVSS Score

VectorL
ComplexityL
PrivilegesL
User InteractionR
ScopeC
ConfidentialityH
IntegrityH
AvailabilityH
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H

Vulnerability Location

SourceLine 132
internal/command/mcp/server.go
runServer()
SinkLine 570
internal/command/mcp/config.go
UpdateConfig()

Source-to-Sink Analysis

1
internal/command/mcp/server.go:132

The setup workflow reads the logged-in user's Fly token and places it in the persistent proxy argument list.

GO
if token := getAccessToken(ctx); token != "" {
  args = append(args, "--bearer-token", token)
}
2
internal/command/mcp/server.go:145

The complete credential-bearing command is passed to the client-specific configuration updater.

GO
return mcpConfig.UpdateConfig(client, serverName, command, args)
3
internal/command/mcp/config.go:570

Before the fix, normal creation and rename honored the ambient umask, so a newly serialized secret could remain world-readable.

GO
if err := os.WriteFile(tmp, contents, 0o666); err != nil { return err }
return os.Rename(tmp, path)

Impact Analysis

Critical Impact

A separate local user can steal the victim's long-lived Fly API token and exercise the token's cloud permissions, potentially reading application data, changing deployments, or deleting resources according to the victim's account authority.

Attack Surface

Local multi-user Unix systems where flyctl mcp server configures a stream/SSE MCP client and persists a Fly bearer token.

Preconditions

The victim must run the setup command while logged in to Fly, and the generated client config must be in a directory readable by another local user. The attacker needs only an unprivileged local account.

Proof of Concept

Environment Setup

Use an isolated Unix host with two unprivileged accounts and a vulnerable flyctl build. Set the victim shell's umask to 022.

Target Configuration

Log the victim into a test Fly organization and configure a stream/SSE MCP client so flyctl persists --bearer-token in its JSON settings.

Exploit Delivery

From the second local account, read the generated configuration and locate the bearer-token argument.

Outcome

PR #5192 forces the final file to 0600; the second account receives a permission error and cannot read the credential.

Expected Response: On the vulnerable build, the file mode is 0644 and the second account can read the complete token value.

Run this level of analysis on your repo.

Winfunc traces source-to-sink paths, validates exploitability, and gives your team patch-ready remediation.

Vulnerability Detection