fix(security): validate URLs in config API to prevent SSRF

AD
5mo ago
+41-0

Summary

Fixes #1139 — Second-Order SSRF via unprotected config API controlling SearXNG URL.

Problem

The POST /api/config endpoint accepts any URL value without validation. An attacker can set search.searxngURL to internal/metadata addresses (169.254.169.254, 10.x.x.x, localhost), then trigger server-side requests via /api/discover that hit internal infrastructure.

Fix

Add isPrivateOrMetadataUrl() validation that rejects:

  • Localhost (127.0.0.1, ::1, localhost)
  • AWS/GCP metadata endpoints (169.254.169.254, metadata.google.internal)
  • RFC 1918 private ranges (10.x, 172.16-31.x, 192.168.x)
  • IPv6 link-local and ULA (fe80:, fc/fd)
  • Any .internal TLD

Applied only to config keys that store URLs (search.searxngURL).

Notes

  • This is a defense-in-depth measure. Ideally the config API should also require authentication (separate concern, separate PR).
  • Does not break legitimate SearXNG URLs (public domains pass validation).

Summary by cubic

Validate URL inputs in the config API to block SSRF. Prevents setting search.searxngURL to private, loopback, link‑local, or metadata addresses, addressing #1139.

  • Bug Fixes
    • Added isPrivateOrMetadataUrl() and applied to search.searxngURL; blocked URLs return 400 with a clear error.
    • Blocks localhost/0.0.0.0, 127.0.0.0/8, 169.254.0.0/16, RFC1918 ranges, IPv6 ::1 and link‑local/ULA, .internal, and metadata.google.internal.