rust-lang / rust-lang/rust-clippy

New lint proposal: reqwest_redirect_policy_unset

Open
#17,019 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.