CVE-2026-39922 - GeoNode service registration SSRF

GeoNode service registration can fetch a user-supplied OGC service URL during validation. In affected deployments, an authenticated user can submit a crafted WMS service URL that makes the GeoNode backend connect to arbitrary targets instead of only intended map services. That turns the GeoNode server into an SSRF probe against loopback, RFC1918 private ranges, link-local addresses, and cloud metadata endpoints.

Treat this as an application egress and trust-boundary fix, not just a scanner suppression. The safest PR inventories every place the product registers remote WMS, WFS, WCS, WMTS, or GeoServer endpoints; constrains outbound requests; and documents the version ambiguity in the public records.

When to use it

Use this recipe when a repository deploys GeoNode service registration, catalog/import workflows, or equivalent geospatial service ingestion that can fetch user-supplied URLs. It is designed for source-code/deployment remediation, SSRF allow-list review, internal service protection, tenant boundary checks, and evidence that service registration cannot reach private or metadata endpoints.

Inputs

  • GeoNode version, Python/package pins, container/chart/manifests, service registration settings, URL validation code, egress policy, and generated dependency or SBOM reports.
  • Source/config paths that register external services, fetch WMS/WFS/WMTS endpoints, validate URLs, proxy requests, cache service metadata, or expose import/catalog forms.
  • Regression fixtures for allowed public services, private IPs, localhost, link-local/metadata endpoints, DNS rebinding-like hostnames, redirects, and expected denial.
  • Boundary evidence: tenant/service owners, allowed provider domains, internal network reachability, logs, import owner, and rollout owner.

Affected versions

There is source ambiguity as of 2026-06-08:

  • NVD analysis and CPE data: GeoNode 4.0.0 through versions before 4.4.5, and GeoNode 5.0.0 through versions before 5.0.2.
  • Current NVD/VulnCheck description: GeoNode 4.4.5 and 5.0.2, and prior releases in those branches.
  • Patch references: GeoNode 4.4.5 and 5.0.2 release notes are listed as patch references in NVD history, but the GitHub Security Advisory URL cited by NVD was not publicly fetchable during this recipe update.

Do not suppress a finding for 4.4.5 or 5.0.2 solely because a scanner treats those as fixed. Confirm the vendor advisory, inspect local URL validation, and verify egress controls. If the repository is on an older 4.x or 5.0.x build, upgrade at least to the newest available vendor release and keep the SSRF controls below.

Indicator-of-exposure

  • The repository depends on, vendors, forks, builds, or deploys GeoNode.
  • GeoNode service registration is enabled for users outside a trusted operator group.
  • Users can add remote OGC services such as WMS, WFS, WCS, WMTS, GeoServer, or ArcGIS endpoints through UI, API, import jobs, fixtures, management commands, or automation.
  • The backend validates service URLs by making outbound HTTP requests without a strict destination allowlist, DNS/IP classification, redirect revalidation, and private-network blocking.
  • GeoNode runs in a cloud, Kubernetes, or internal-network environment where backend egress can reach metadata endpoints, service discovery, databases, admin panels, kubelet APIs, Redis, Elasticsearch, GeoServer admin endpoints, or internal tile services.
  • Error messages, timing, imported metadata, previews, logs, or audit events can reveal whether internal hosts responded.

Quick checks:

rg -n "geonode|GeoNode|service registration|ServiceRegistration|WMS|WFS|WCS|WMTS|GeoServer|ArcGIS|OGC|ows|GetCapabilities|requests\\.|urlopen|httpx|httplib|metadata|169\\.254\\.169\\.254|localhost|127\\.0\\.0\\.1" .
python -m pip show geonode
python -m pip freeze | rg -i "^(geonode|django-geonode)=="
rg -n "GEONODE|OGC|WMS|WFS|WCS|WMTS|GEOSERVER|PROXY|ALLOWED_HOSTS|NO_PROXY|HTTP_PROXY|HTTPS_PROXY|169\\.254\\.169\\.254" Dockerfile* docker-compose*.yml compose*.yml charts k8s helm values*.yaml .env* settings*.py config . 2>/dev/null

Windows:

rg -n "geonode|GeoNode|service registration|ServiceRegistration|WMS|WFS|WCS|WMTS|GeoServer|ArcGIS|OGC|ows|GetCapabilities|requests\\.|urlopen|httpx|httplib|metadata|169\\.254\\.169\\.254|localhost|127\\.0\\.0\\.1" .
python -m pip show geonode
python -m pip freeze | rg -i "^(geonode|django-geonode)=="
rg -n "GEONODE|OGC|WMS|WFS|WCS|WMTS|GEOSERVER|PROXY|ALLOWED_HOSTS|NO_PROXY|HTTP_PROXY|HTTPS_PROXY|169\\.254\\.169\\.254" Dockerfile* docker-compose*.yml compose*.yml charts k8s helm values*.yaml .env* settings*.py config .

Do not test by pointing a live GeoNode instance at loopback, cloud metadata, cluster services, admin panels, customer endpoints, or third-party map servers you do not own.

Remediation strategy

  • Upgrade GeoNode to the newest available vendor release on the branch the deployment can support. If the scanner says 4.4.5 or 5.0.2 is fixed, still verify the code-level SSRF controls because public records disagree.
  • Restrict service registration to trusted operators until URL validation and egress controls are confirmed.
  • Add or verify a single server-side URL validator for all OGC import paths. It should allow only http and https, require an explicit allowlist or approved domain list when possible, resolve DNS before connecting, reject loopback/private/link-local/multicast/unspecified/reserved addresses, block cloud metadata endpoints, and re-check every redirect destination.
  • Treat DNS rebinding as in scope. Resolve the host close to connect time, bind the resolved address classification to the request, and set short timeouts and response-size limits for GetCapabilities or service validation fetches.
  • Enforce network egress policy outside the application as a backstop: Kubernetes NetworkPolicy, cloud firewall rules, proxy allowlists, IMDSv2 or equivalent metadata protections, and deny rules for RFC1918/link-local ranges unless a specific internal map service is explicitly approved.
  • Keep GeoServer admin endpoints, internal tile services, search indices, databases, queues, metadata services, and service discovery endpoints outside GeoNode egress reach unless they are required and separately authenticated.
  • Add safe regression tests against local fake hosts and mocked DNS/HTTP clients. Do not probe real internal services.

The prompt

You are remediating CVE-2026-39922 / GHSA-hw9r-6m78-w6h3, a GeoNode service
registration SSRF where authenticated users can submit crafted OGC service URLs
that make the backend contact arbitrary internal or external targets during
validation. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades or contains GeoNode, fixes
  URL validation for service registration, adds safe SSRF regression tests,
  refreshes generated artifacts, and documents operator egress requirements, or
- TRIAGE.md if this repository does not control an affected GeoNode runtime,
  fork, image, deployment, service-registration path, or OGC import workflow.

## Rules

- Scope only CVE-2026-39922 / GHSA-hw9r-6m78-w6h3 and directly related GeoNode
  service-registration, OGC import, URL validation, redirect, DNS, and egress
  controls.
- Treat cloud metadata, internal hosts, GeoServer admin endpoints, databases,
  queues, credentials, cookies, bearer tokens, map-service credentials, customer
  data, uploaded geospatial data, and service-registration logs as sensitive.
- Do not probe production, cloud metadata, loopback, RFC1918 targets,
  link-local services, Kubernetes APIs, GeoServer admin panels, databases, or
  third-party map services you do not own.
- Do not remove authentication, operator approval, allowlists, egress policy,
  audit logging, SSRF tests, or service-registration controls to silence the
  finding.
- Do not auto-merge.

## Steps

1. Inventory every GeoNode runtime controlled by this repository: pip
   dependencies, Docker images, compose files, Helm/Kubernetes manifests,
   settings modules, forks, vendored patches, deployment docs, SBOMs,
   generated dependency reports, and service-registration customizations.
2. Determine the resolved GeoNode version and branch. Record the source
   ambiguity: NVD analysis/CPE identifies 4.x before 4.4.5 and 5.0.x before
   5.0.2, while current NVD/VulnCheck text names 4.4.5 and 5.0.2 and prior.
3. Search for every remote-service registration path: WMS, WFS, WCS, WMTS,
   GeoServer, ArcGIS, OGC API Features, imports, fixtures, management commands,
   REST endpoints, UI forms, background jobs, and custom validators.
4. If this repository only consumes an externally owned GeoNode service, stop
   with `TRIAGE.md` listing checked files, owning team/vendor, version evidence,
   and required containment questions.
5. Upgrade controlled GeoNode deployments to the newest available vendor
   release compatible with the branch. Refresh lockfiles, image tags, image
   digests, SBOMs, deployment manifests, and generated dependency reports.
6. Patch or verify service URL validation:
   - allow only `http` and `https`;
   - reject credentials in URLs unless explicitly required and safely stored;
   - normalize and parse URLs with a structured parser;
   - reject loopback, localhost, RFC1918 private, link-local, multicast,
     unspecified, reserved, IPv4-mapped IPv6, and cloud metadata addresses;
   - resolve DNS and classify every returned address before connecting;
   - revalidate each redirect target before following it;
   - require a service-domain allowlist for production where feasible;
   - set strict connect/read timeouts and maximum response sizes.
7. Add egress containment where the repo controls infrastructure:
   - deny metadata endpoints such as `169.254.169.254`;
   - block private and link-local ranges by default;
   - allow only approved external OGC/map-service domains or a controlled
     outbound proxy;
   - separate GeoNode application egress from GeoServer admin, databases,
     queues, cluster APIs, and search services.
8. Restrict service registration to trusted operators or approval workflows
   until the patch and egress policy are deployed.
9. Add safe regression tests:
   - allowed public test service URLs pass through a mocked HTTP client;
   - loopback, private, link-local, metadata, IPv6 loopback, IPv4-mapped IPv6,
     malformed, credentialed, oversized, slow, and redirect-to-private URLs are
     rejected;
   - service-registration errors do not leak response bodies, internal host
     names, credentials, or timing-sensitive details;
   - tests use mocks, local fake resolvers, or reserved documentation domains
     instead of live internal endpoints.
10. Add a PR body section named `CVE-2026-39922 operator actions` that states:
    - GeoNode versions before and after;
    - how the 4.4.5/5.0.2 advisory ambiguity was resolved;
    - every OGC service-registration path checked;
    - whether service registration is operator-only, user-accessible, or
      approval-gated;
    - app-level URL validation and network-level egress controls;
    - whether cloud metadata and internal services are unreachable from
      GeoNode;
    - which validation commands passed.
11. Run available validation: dependency install, lockfile integrity, URL
    validation unit tests, service-registration tests, Django tests,
    lint/typecheck, container build, manifest rendering, SBOM refresh, and
    dependency/security scans.
12. Use PR title:
    `fix(sec): remediate CVE-2026-39922 in GeoNode service registration`

## Stop conditions

- No repository-controlled GeoNode runtime, fork, image, service-registration
  path, or OGC import workflow exists.
- The only affected GeoNode deployment is owned by another team or vendor; name
  that owner and required version/egress questions in `TRIAGE.md`.
- The public advisory records disagree and local code/version evidence cannot
  determine whether the deployment is fixed; document the ambiguity instead of
  suppressing the finding.
- Verifying exposure would require production SSRF probes, internal network
  scanning, cloud metadata access, third-party service probing, customer data,
  or credentials.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Output contract

  • A reviewer-ready PR or change request that upgrades GeoNode, hardens service URL validation, adds SSRF regression checks, restricts egress, and documents catalog/operator review.
  • Or a TRIAGE.md file that lists inspected dependencies/config/fetch paths, owner, observed version, service-registration boundary, required fix, and residual risk.
  • The output must include exact validation commands and must not probe production internal networks, metadata services, or tenant-private service endpoints.

Verification - what the reviewer looks for

  • GeoNode version evidence is explicit and the PR does not hide the public 4.4.5/5.0.2 source ambiguity.
  • Service registration and OGC import paths use a shared server-side URL validation boundary before outbound requests.
  • Redirects and DNS results are revalidated before connect, not only at initial string-parse time.
  • Loopback, private, link-local, IPv4-mapped IPv6, metadata, and reserved destinations are blocked in tests and by infrastructure egress policy where the repo owns deployment manifests.
  • Service-registration errors and logs do not disclose internal hostnames, credentials, map-service tokens, response bodies, or customer data.
  • The PR documents whether registration is operator-only, approval-gated, or user-accessible after remediation.

Watch for

  • Suppressing 4.4.5 or 5.0.2 findings without explaining why the current NVD/VulnCheck wording no longer applies.
  • Validating only the UI form while API imports, fixtures, background jobs, or management commands still fetch arbitrary service URLs.
  • Blocking 127.0.0.1 but allowing IPv6 loopback, IPv4-mapped IPv6, link-local, DNS rebinding, redirect-to-private, or cloud metadata targets.
  • Depending only on application string filters without network egress policy.
  • Testing against live internal hosts, metadata services, or third-party map services instead of mocked clients and reserved test addresses.

References