CVE-2026-79717: Galaxy_ng: galaxy_ng: blind ssrf via namespace avatar_url with no private-address restriction
A server-side request forgery (SSRF) vulnerability was found in galaxyng, the Ansible Galaxy server plugin for Pulp. An authenticated user with namespace management permissions can set a namespace avatar URL to an arbitrary address, including internal networks, loopback, or cloud instance metadata endpoints. A background worker fetches that URL without checking the destination, which lets the attacker probe internal services and enumerate reachable IP addresses. The HTTP client is also configured without an overall timeout, so a slow or non-responsive target can pin workers and cause a denial of service.
Other sources
galaxyng is a Pulp plugin powering Ansible Galaxy and Ansible Automation Platform Private Automation Hub. A server-side request forgery (SSRF) exists in the namespace avatar download path.
In galaxyng/app/api/v3/serializers/namespace.py, avatarurl is a DRF URLField. That field validates URL syntax and scheme (http/https) only. It does not resolve the hostname or filter private, loopback, link-local, or cloud-metadata addresses. On namespace create, downloadlogo is always True. On update, downloadlogo is True whenever avatarurl is present. The serializer then dispatches a Pulp task that calls downloadavatar() in galaxyng/app/tasks/namespaces.py.
downloadavatar() builds an aiohttp session with ClientTimeout(total=None, sockconnect=600, sockread=600) and passes the user-supplied URL to pulpcore HttpDownloader with no address restriction and no redirect-target revalidation. The Pulp worker therefore requests whatever address the publisher supplied, including RFC1918, 127.0.0.0/8, 169.254.0.0/16, and cloud metadata endpoints.
The SSRF is blind: the response is stored only if it passes image validation (PIL ImageField or SVG). Non-image bodies are discarded, so this is not direct credential exfiltration. The attacker still gets a binary oracle via namespace avatarsha256 (updated vs unchanged), which is enough to enumerate reachable internal IPs and ports from the worker's network. The total=None timeout also lets a slow or hanging target pin a worker, which is a denial-of-service angle.
Privilege required is an authenticated user with galaxy.changenamespace or galaxy.addnamespace. In community Galaxy that includes a user's own namespace.
Affected: galaxyng (verified on current main, HEAD 2bc7189 at clone time). No upstream fix identified in the examined tree. Reporter: Arpit Jain (GitHub arpitjain099), independent security researcher. PSIRT ticket: PSIRTSUPT-22101 Distinct from GHSA-hc3x-6pf5-pmj3 (legacy role import path).
— Red Hat
Affected Software
Event History
Frequently Asked Questions
Which users can trigger the server-side requests?
An authenticated user needs namespace management permissions. They can supply an arbitrary HTTP or HTTPS avatar URL when creating a namespace or when updating one with avatar_url present.
Does the avatar download need to be explicitly enabled to be triggered?
No. Namespace creation always sets download_logo to true, and updates set it to true whenever avatar_url is included. The background worker then fetches the supplied URL.
What targets can be reached from the affected server?
The URL validation checks syntax and permits HTTP or HTTPS, but does not resolve or restrict destinations. This allows requests to internal networks, loopback and link-local addresses, and cloud instance metadata endpoints reachable from the worker.
Is the impact limited to data access?
No. The SSRF is blind and can be used to probe internal services and enumerate reachable IP addresses. Because the HTTP client has no overall timeout, slow or non-responsive destinations can also pin background workers and cause denial of service.