{"record":{"id":"22a0c648d91cdfa5","repo":"Kareadita/Kavita","slug":"url-blocked-address","errorCode":null,"errorMessage":"url-blocked-address","messagePattern":"url-blocked-address","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Common/Helpers/FlurlConfiguration.cs","lineNumber":88,"sourceCode":"                        foreach (var addr in addresses)\n                        {\n                            if (IpBlocklist.IsBlockedAddress(addr)) continue;\n\n                            var socket = new Socket(addr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);\n                            try\n                            {\n                                await socket.ConnectAsync(new IPEndPoint(addr, context.DnsEndPoint.Port), ct);\n                                return new NetworkStream(socket, ownsSocket: true);\n                            }\n                            catch\n                            {\n                                socket.Dispose();\n                                continue;\n                            }\n                        }\n\n\n                        throw new KavitaException(\"url-blocked-address\");\n                    }\n                };\n\n                var httpClient = new HttpClient(handler);\n                client = new FlurlClient(httpClient);\n                SafeClients[key] = client;\n            }\n\n            return client.Request(url);\n        }\n    }\n}\n","sourceCodeStart":70,"sourceCodeEnd":101,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Common/Helpers/FlurlConfiguration.cs#L70-L101","documentation":"Thrown by FlurlConfiguration.CreateSafeRequest's ConnectCallback after every resolved IP for the target host was either blocked by IpBlocklist (loopback, private, reserved, CGNAT, link-local, multicast ranges) or failed its TCP connect. This is Kavita's SSRF guard preventing requests to internal/private addresses, so it surfaces as HTTP 500 with 'url-blocked-address'.","triggerScenarios":"A user-supplied or external URL resolves only to private/reserved IPs (e.g. 127.0.0.1, 10.x, 192.168.x, ::1), or DNS rebinding points a public hostname at an internal IP, or every resolved address refused the connection. Triggered by cover upload-by-url, any Flurl CreateSafeRequest call against such a host.","commonSituations":"Testing against localhost/lan URLs; a misconfigured cover/book image URL that points at an internal host; DNS rebinding attack; the target host is genuinely unreachable (all IPs fail connect) so the blocklist-or-connect loop exhausts.","solutions":["Use a public hostname/IP that resolves to a routable address — the blocklist rejects private ranges by design.","If you control the source data, validate the URL is public before handing it to CreateSafeRequest.","If the target is legitimately internal and trusted, use ConfigureClientForUrl (no SSRF check) only for hardcoded trusted hosts, never user input.","Fix the target host connectivity if the real problem is refused connections rather than blocked IPs."],"exampleFix":"// before\nvar req = FlurlConfiguration.CreateSafeRequest(\"http://192.168.1.5/cover.jpg\");\n\n// after\nvar req = FlurlConfiguration.CreateSafeRequest(\"https://cdn.example.com/cover.jpg\");","handlingStrategy":"try-catch","validationCode":"var uri = new Uri(url);\nforeach (var addr in await Dns.GetHostAddressesAsync(uri.Host))\n    if (IpBlocklist.IsBlockedAddress(addr))\n        throw new InvalidOperationException(\"URL resolves to a blocked address\");","typeGuard":null,"tryCatchPattern":"try { var resp = await FlurlConfiguration.CreateSafeRequest(url).GetAsync(); }\ncatch (KavitaException ex) when (ex.Message == \"url-blocked-address\")\n{ /* surface to user: pick a public URL */ }","preventionTips":["Only feed public, routable URLs into CreateSafeRequest.","Pre-validate URLs server-side with IpBlocklist before the request.","Reserve ConfigureClientForUrl (no SSRF check) for hardcoded trusted hosts only."],"tags":["security","ssrf","network","flurl","http"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}