transport: reject initial frames with wild body sizes (#4620)
If someone opens a connection to port 9042 and sends some random bytes, there is a 1 in 64 probability we'll recognize it as a valid frame (since we only check the version byte, allowing versions 1-4) and we'll try to read frame.length bytes for the body. If this value is very large, we'll run out of memory very quickly. Fix this by checking for reasonable body size (100kB). The initial message must be a STARTUP, whose body is a [string map] of options, of which just three are recognized. 100kB is plenty for future expansion. Note that this does not replace true security on listening ports and only serves to protect against mistakes, not attacks. An attacker can easily exhaust server memory by opening many connections and trickle-feeding them small amounts of data so they appear alive. We can't use the config item native_transport_max_frame_size_in_mb, because that can be legitimately large (and the default is atrocious, 256MB). Fixes #4366.
This commit is contained in:
committed by
Tomasz Grabiec
parent
eb496b5eae
commit
c987397e52
@@ -329,7 +329,15 @@ cql_server::connection::read_frame() {
|
||||
temporary_buffer<char> full(frame_size());
|
||||
full.get_write()[0] = _version;
|
||||
std::copy(tail.get(), tail.get() + tail.size(), full.get_write() + 1);
|
||||
return make_ready_future<ret_type>(parse_frame(std::move(full)));
|
||||
auto frame = parse_frame(std::move(full));
|
||||
// This is the very first frame, so reject obviously incorrect frames, to
|
||||
// avoid allocating large amounts of memory for the message body
|
||||
if (frame.length > 100'000) {
|
||||
// The STARTUP message body is a [string map] containing just a few options,
|
||||
// so it should be smaller that 100kB. See #4366.
|
||||
throw exceptions::protocol_exception(format("Initial message size too large ({:d}), rejecting as invalid", frame.length));
|
||||
}
|
||||
return make_ready_future<ret_type>(frame);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user