Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.12.1] Issue in ureq::Response::into_reader() example code #940

Open
Monadic-Cat opened this issue Jan 21, 2025 · 1 comment
Open

[2.12.1] Issue in ureq::Response::into_reader() example code #940

Monadic-Cat opened this issue Jan 21, 2025 · 1 comment

Comments

@Monadic-Cat
Copy link

Monadic-Cat commented Jan 21, 2025

The doc comment for Response::into_reader() says this:

Note: If you use read_to_end() on the resulting reader, a malicious server might return enough bytes to exhaust available memory. If you’re making requests to untrusted servers, you should use .take() to limit the response bytes read.

This is all well and good, but it makes me interpret the example snippet below as being intended to handle that threat model, wherein the server may return a response crafted to cause you to crash in some way.

use std::io::Read;
let resp = ureq::get("http://httpbin.org/bytes/100")
    .call()?;

assert!(resp.has("Content-Length"));
let len: usize = resp.header("Content-Length")
    .unwrap()
    .parse()?;

let mut bytes: Vec<u8> = Vec::with_capacity(len);
resp.into_reader()
    .take(10_000_000)
    .read_to_end(&mut bytes)?;

assert_eq!(bytes.len(), len);

(Note that I am ignoring the asserts here, as well as .unwrap(), "don't panic if you care about not panicking when the server does something wrong" is well known enough anyway...)

The problem here is that the Content-Length header is being trusted to be okay to pass to Vec::with_capacity(), when it's server controlled in exactly the same way as the actual size of the body. If a user is using .take(10_000_000) to limit the size of the body they'll process, they should also use std::cmp::min(len, 10_000_000) when computing what to pass into Vec::with_capacity() there.

@algesten
Copy link
Owner

Good point!

I will accepts PRs against the two 2.x branches: 2.11.x-msrv1.67 and 2.12.x-msrv1.71 though I think the more important issue is to clarify this in the 3.x/main branch and the API there is different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants