rust-lang / rust-lang/rust-clippy
New lint proposal: reqwest_redirect_policy_unset
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
What it does
Lints uses of `reqwest::blocking::get`, `reqwest::Client::new()`, or `reqwest::Client::builder().build()` followed by `.get(url).send()` when:
- The URL argument data-flows from a function parameter, and
- The client is not configured with `.redirect(...)` before use.
Why is this bad
The default `reqwest::Client` has `redirect: Policy::limited(10)`. It follows up to 10 redirects across arbitrary hosts with no host allowlist. When the URL is user-controlled, this is the canonical SSRF anti-pattern: an attacker-supplied URL can redirect to `http://169.254.169.254/...\` (AWS IMDSv1), internal services, or metadata endpoints.
Real-world precedent
- HuggingFace `text-generation-inference` `fetch_image` at `router/src/validation.rs:570`. Reported under CWE-918 in a separate advisory.
- Numerous Rust crates downloading user-provided URLs (CI build tooling, package fetchers, image hosts).
Suggested example
Bad:
```rust
fn fetch_image(user_url: &str) -> Result<Vec, reqwest::Error> {
let resp = reqwest::blocking::get(user_url)?;
Ok(resp.bytes()?.to_vec())
}
```
Good:
```rust
fn fetch_image(user_url: &str) -> Result<Vec, reqwest::Error> {
let client = reqwest::blocking::Client::builder()
.redirect(reqwest::redirect::Policy::none())
.build()?;
let resp = client.get(user_url).send()?;
Ok(resp.bytes()?.to_vec())
}
```
Lint category and configuration
Suggested category: `suspicious` (rust-clippy convention for SSRF / security-flavored lints). Override-able with `#[allow(...)]` when the URL is known constant.
Drawbacks
- Requires inter-procedural taint awareness, which clippy already has for several lints. Effort is moderate.
- May false-positive on internal-only services where the URL happens to flow from a parameter but the parameter is always trusted. Override mechanism handles that.
Next steps
If maintainers want the lint, I will draft the implementation with table-driven UI tests and submit a PR.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading Clippy’s existing inter-procedural taint-aware lints and their table-driven UI tests; the issue does not name specific files. Define the cases for user-controlled URLs, unconfigured redirects, and allow overrides, then consider the work done when the lint and representative UI tests cover the proposed examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- security, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100