Skip to content

Commit 4f780bf

Browse files
committed
Limit backend messages length to prevent DoS
1 parent 5bc7d0e commit 4f780bf

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

tokio-postgres/src/codec.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ impl FallibleIterator for BackendMessages {
3535
}
3636
}
3737

38-
pub struct PostgresCodec;
38+
pub struct PostgresCodec {
39+
pub max_message_size: Option<usize>,
40+
}
3941

4042
impl Encoder<FrontendMessage> for PostgresCodec {
4143
type Error = io::Error;
@@ -64,6 +66,15 @@ impl Decoder for PostgresCodec {
6466
break;
6567
}
6668

69+
if let Some(max) = self.max_message_size {
70+
if len > max {
71+
return Err(io::Error::new(
72+
io::ErrorKind::InvalidInput,
73+
"message too large",
74+
));
75+
}
76+
}
77+
6778
match header.tag() {
6879
backend::NOTICE_RESPONSE_TAG
6980
| backend::NOTIFICATION_RESPONSE_TAG

tokio-postgres/src/config.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ pub struct Config {
185185
pub(crate) target_session_attrs: TargetSessionAttrs,
186186
pub(crate) channel_binding: ChannelBinding,
187187
pub(crate) replication_mode: Option<ReplicationMode>,
188+
pub(crate) max_backend_message_size: Option<usize>,
188189
}
189190

190191
impl Default for Config {
@@ -217,6 +218,7 @@ impl Config {
217218
target_session_attrs: TargetSessionAttrs::Any,
218219
channel_binding: ChannelBinding::Prefer,
219220
replication_mode: None,
221+
max_backend_message_size: None,
220222
}
221223
}
222224

@@ -472,6 +474,17 @@ impl Config {
472474
self.replication_mode
473475
}
474476

477+
/// Set limit for backend messages size.
478+
pub fn max_backend_message_size(&mut self, max_backend_message_size: usize) -> &mut Config {
479+
self.max_backend_message_size = Some(max_backend_message_size);
480+
self
481+
}
482+
483+
/// Get limit for backend messages size.
484+
pub fn get_max_backend_message_size(&self) -> Option<usize> {
485+
self.max_backend_message_size
486+
}
487+
475488
fn param(&mut self, key: &str, value: &str) -> Result<(), Error> {
476489
match key {
477490
"user" => {

tokio-postgres/src/connect_raw.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ where
9090
let stream = connect_tls(stream, config.ssl_mode, tls).await?;
9191

9292
let mut stream = StartupStream {
93-
inner: Framed::new(stream, PostgresCodec),
93+
inner: Framed::new(stream, PostgresCodec {
94+
max_message_size: config.max_backend_message_size,
95+
}),
9496
buf: BackendMessages::empty(),
9597
delayed: VecDeque::new(),
9698
};

0 commit comments

Comments
 (0)