No. According to the reqwest ClientBuilder documentation, the default for timeout is "no timeout", connect_timeout defaults to None, and read_timeout defaults to no timeout. A default client can wait indefinitely on a slow server, so set at least a total timeout and a connect timeout on every client you build.
What each timeout does
The docs describe three separate settings:
| Setting | Meaning | Default |
|---|---|---|
| timeout | A total request timeout, from when the request starts connecting until the response body has finished | None |
| connect_timeout | Timeout for only the connect phase | None |
| read_timeout | Applies to each read operation and resets after a successful read | None |
The total timeout and the read timeout guard against different things. A total timeout puts a hard ceiling on a call. A read timeout detects a peer that has gone quiet, but a peer that keeps sending a byte now and then can hold a request open far beyond what you intended unless a total timeout is also set.
Redirects and certificates
Two other documented defaults are worth knowing. The default redirect policy follows up to 10 redirects. For calls to user supplied URLs, consider a tighter policy or none, since redirects can carry a request to a host you did not expect.
The docs also warn about danger_accept_invalid_certs: "You should think very carefully before using this method." If invalid certificates are trusted, any certificate for any site is trusted. The method name is a hint that it belongs in tests at most. Add a code scan rule to catch it, in the same spirit as disabled TLS verification in other languages.
For the TLS floor, the docs mark min_tls_version as deprecated in favour of tls_version_min, and say the default is the TLS backend's own default. If you need a specific floor, set it explicitly rather than inheriting whatever the backend chooses.
A safe starting client
use std::time::Duration;
let client = reqwest::Client::builder()
.connect_timeout(Duration::from_secs(3))
.timeout(Duration::from_secs(10))
.read_timeout(Duration::from_secs(5))
.redirect(reqwest::redirect::Policy::limited(3))
.build()?;
Build the client once and share it. Creating a client per request throws away connection pooling and costs more than it saves.
Why this is a security issue
If an attacker controls a URL your service fetches, such as a webhook target, an avatar link or a link preview, they can point you at a server that never finishes responding. Without timeouts, those calls accumulate until your task pool or connection limit is exhausted. Pair timeouts with limits on response size and with an allow list when you can.
Steps
- Search for reqwest::get and Client::new. Both use defaults.
- Replace them with a configured shared client.
- Set total, connect and read timeouts.
- Reduce the redirect limit for user supplied URLs.
- Cap response size when you read the body.
- Search for danger_accept_invalid_certs and remove it from production code.
Try it yourself
Click through it at your own pace, or open it full screen. Watch how a code scan flags a risky call at the exact line, such as a client built with defaults.
Quick check
Can I set a timeout per request instead?
Yes, requests can override the client setting with their own timeout. A client level default still protects calls where someone forgot.
Is a timeout enough protection against SSRF?
No. A timeout limits how long a call waits. Preventing requests to internal addresses needs separate validation of the destination.
Safeguard's dependency scanning and SBOM generation read Rust lock files, so the crates you ship are inventoried and checked against advisories, and the free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.