Skip to main content

fraiseql_core/http/
client.rs

1//! SSRF-safe HTTP client construction.
2//!
3//! All outbound HTTP clients that contact external services (OIDC JWKS endpoints,
4//! Vault, federation subgraphs, webhooks) must be built with this module to ensure
5//! a consistent security baseline.
6
7use std::time::Duration;
8
9use reqwest::{Client, ClientBuilder, redirect};
10
11/// Build an HTTP client that is safe for SSRF-sensitive outbound requests.
12///
13/// # Policy
14///
15/// - **Redirects disabled**: a redirect response (`3xx`) is treated as an error, preventing
16///   redirect-chain attacks that bypass URL-validation guards applied to the initial URL (e.g. a
17///   subgraph redirecting to `169.254.169.254`).
18/// - **HTTPS only**: plain HTTP connections are rejected, preventing protocol-downgrade via
19///   redirect.
20/// - **Caller-supplied timeout**: applied to all requests; prevents slow-loris hangs on malicious
21///   or misconfigured endpoints.
22///
23/// # Errors
24///
25/// Returns a [`reqwest::Error`] if TLS initialisation fails (extremely rare;
26/// indicates a platform TLS misconfiguration).
27pub fn build_ssrf_safe_client(timeout: Duration) -> reqwest::Result<Client> {
28    ClientBuilder::new()
29        .redirect(redirect::Policy::none())
30        .https_only(true)
31        .timeout(timeout)
32        .build()
33}