{"id":"GHSA-8xq3-w9fx-74rv","summary":"webfinger.js Blind SSRF Vulnerability","details":"### Description\nThe lookup function takes a user address for checking accounts as a feature, however, as per\nthe ActivityPub spec (https://www.w3.org/TR/activitypub/#security-considerations), on the\nsecurity considerations section at B.3, access to Localhost services should be prevented while\nrunning in production. The library does not prevent Localhost access (neither does it prevent\nLAN addresses such as 192.168.x.x) , thus is not safe for use in production by ActivityPub\napplications. The only check for localhost is done for selecting between HTTP and HTTPS\nprotocols, and it is done by testing for a host that starts with the string “localhost” and ends with\na port. Anything else (such as “127.0.0.1” or “localhost:1234/abc”) would not be considered\nlocalhost for this test.\n\nIn addition, the way that the function determines the host, makes it possible to access any path\nin the host, not only “/.well-known/...” paths:\n\n```javascript\nif (address.indexOf('://') \u003e -1) {\n  // other uri format\n  host = address.replace(/ /g,'').split('/')[2];\n} else {\n  // useraddress\n  host = address.replace(/ /g,'').split('@')[1];\n}\n\nvar uri_index = 0; // track which URIS we've tried already\nvar protocol = 'https'; // we use https by default\n\nif (self.__isLocalhost(host)) {\n  protocol = 'http';\n}\n\nfunction __buildURL() {\n  var uri = '';\n  if (! address.split('://')[1]) {\n  // the URI has not been defined, default to acct\n    uri = 'acct:';\n  }\n  return protocol + '://' + host + '/.well-known/' +URIS[uri_index] + '?resource=' + uri + address;\n}\n```\n\nIf the address is in the format of a user address (user@host.com), the host will be anything\nafter the first found @ symbol. Since no other test is done, an adversary may pass a specially\ncrafted address such as user@localhost:7000/admin/restricted_page? and reach pages that\nwould normally be out of reach. In this example, the code would treat\nlocalhost:7000/admin/restricted_page? as the host, and the created URL would be\nhttps://localhost:7000/admin/restricted_page?/.well-known/webfinger?resource=acct:use\nr@localhost:7000/admin/restricted_page?. A server listening on localhost:7000 will then\nparse the request as a GET request for the page /admin/restricted_page with the query string\n/.well-known/webfinger?resource=acct:user@localhost:7000/admin/restricted_page?.\n\n### PoC and Steps to reproduce\nThis PoC assumes that there is a server on the machine listening on port 3000, which receives\nrequests for WebFinger lookups on the address /api/v1/search_user, and then calls the lookup\nfunction in webfinger.js with the user passed as an argument. For the sake of the example we\nassume that the server configured webfinger.js with tls_only=false.\n\n\n1. Activate a local HTTP server listening to port 1234 with a “secret.txt” file:\n\n```\npython3 -m http.server 1234\n```\n\n2. Run the following command:\n\n```\ncurl\n\"http://localhost:3000/api/v1/search_user?search=user@localhost:1234/secret.txt\n?\"\n```\n\n3. View the console of the Python’s HTTP server and see that a request for a\n“secret.txt?/.well-known/webfinger?resource=acct:user@localhost:1234/secret.txt\n?” file was performed.\nThis proves that we can redirect the URL to any domain and path we choose, including\nlocalhost and the internal LAN.\n\n\n### Impact\nDue to this issue, any user can cause a server using the library to send GET requests with\ncontrolled host, path and port in an attempt to query services running on the instance’s host or\nlocal network, and attempt to execute a Blind-SSRF gadget in hope of targeting a known\nvulnerable local service running on the victim’s machine.\n\n\n### References\nThe vulnerability was discovered by Ori Hollander of the JFrog Vulnerability Research team.","aliases":["CVE-2025-54590"],"modified":"2025-08-01T18:36:22Z","published":"2025-07-28T16:41:06Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2025-07-28T16:41:06Z","nvd_published_at":"2025-08-01T18:15:55Z","cwe_ids":["CWE-918"],"severity":"MODERATE"},"references":[{"type":"WEB","url":"https://github.com/silverbucket/webfinger.js/security/advisories/GHSA-8xq3-w9fx-74rv"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-54590"},{"type":"WEB","url":"https://github.com/silverbucket/webfinger.js/commit/b5f2f2c957297d25f4d76072963fccaee2e3095a"},{"type":"PACKAGE","url":"https://github.com/silverbucket/webfinger.js"},{"type":"WEB","url":"https://github.com/silverbucket/webfinger.js/releases/tag/v2.8.1"}],"affected":[{"package":{"name":"webfinger.js","ecosystem":"npm","purl":"pkg:npm/webfinger.js"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"2.8.1"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 2.8.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/07/GHSA-8xq3-w9fx-74rv/GHSA-8xq3-w9fx-74rv.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N"}]}