Always block cloud metadata endpoints (IMDS) even when local requests are allowed

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Problem to solve

GitLab's outbound-request filter treats the cloud metadata address (169.254.169.254, IPv6 fd00:ec2::254 / ::ffff:169.254.169.254) as part of the general "local network" range. Enabling Settings → Network → Outbound requests → Allow requests to the local network from webhooks and integrations is therefore all-or-nothing: to permit legitimate internal targets, admins must also re-expose the metadata endpoint. On IaaS the metadata endpoint can return IAM credentials, so an SSRF via a webhook/integration (cf. #413254 (closed)) can lead to credential theft. The allowlist is additive only; it cannot subtract.

Proposal

Add an unconditional denylist for well-known cloud metadata endpoints, enforced before the allow_local_network short-circuit and not overridable by the allowlist:

  • 169.254.169.254 (AWS/GCP/Azure IMDS, GCP metadata.google.internal)
  • fd00:ec2::254 and ::ffff:169.254.169.254 (IPv6 IMDS)
  • (optional, same setting) full link-local ranges 169.254.0.0/16 and fe80::/10

Introduce application setting deny_cloud_metadata_requests (default true), surfaced in Admin → Settings → Network → Outbound requests.

Non-goals

  • Does not affect GitLab's own in-process IMDS use (AWS SDK/Fog fetching instance-role credentials) — that path does not go through UrlBlocker.
  • No behavior change for users who don't allow local requests (metadata already blocked).

Implementation notes

  • Add the metadata IP set as a constant in the gitlab-http_v2 gem; check it in the IP-validation path that currently classifies link-local as local (the code exercised by the url_blocker_spec.rb "allows local requests" shared examples). Confirm exact file path when starting the MR.
  • Add deny_cloud_metadata_requests setting + migration + Admin Network UI toggle.
  • Specs: metadata IPs blocked even when allow_local_network: true (IPv4, IPv6, IPv4-mapped); other RFC1918 remain reachable when local requests allowed.
  • Docs: update doc/security/webhooks.md.

Security & process

  • Hardening enhancement (not a disclosed vuln); file publicly but tag Application Security. Seek PM buy-in for the owning group before the MR.

Links:

Edited by 🤖 GitLab Bot 🤖