CVE-2024-23835: Insufficient Information (NVD-CWE-noinfo)
value: Suricata is a network Intrusion Detection System, Intrusion Prevention System and Network Security Monitoring engine.  Prior to version 7.0.3, excessive memory use during pgsql parsing could lead to OOM-related crashes.  This vulnerability is patched in 7.0.3.  As workaround, users can disable the pgsql app layer parser.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-02-26T16:27Z
Repository: https://github.com/OISF/suricata
Language: Rust
Files changed: rust/src/pgsql/parser.rs
Commit date: 2024-02-06 15:16:43 +0100
Commit message: pgsql: parse auth message within its bound

If the next PDU is already in the slice next, do not use it and
restrict ourselves to the length of this PDU.
Avoids overconsumption of memory by quadratic complexity, when
having many small PDUS in one big chunk being parsed

Ticket: #6411

Diff: diff --git a/rust/src/pgsql/parser.rs b/rust/src/pgsql/parser.rs
index 792fb23a13..4dbb2915c2 100644
--- a/rust/src/pgsql/parser.rs
+++ b/rust/src/pgsql/parser.rs
@@ -717,28 +717,27 @@ pub fn parse_request(i: &[u8]) -> IResult<&[u8], PgsqlFEMessage> {
 
 fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], PgsqlBEMessage> {
     let (i, identifier) = verify(be_u8, |&x| x == b'R')(i)?;
     let (i, length) = verify(be_u32, |&x| x >= 8)(i)?;
     let (i, auth_type) = be_u32(i)?;
-    let (i, payload) = peek(rest)(i)?;
     let (i, message) = map_parser(
         take(length - 8),
         |b: &'a [u8]| {
             match auth_type {
                 0 => Ok((b, PgsqlBEMessage::AuthenticationOk(
                             AuthenticationMessage {
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 3 => Ok((b, PgsqlBEMessage::AuthenticationCleartextPassword(
                             AuthenticationMessage {
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 5 => {
                     let (b, salt) = all_consuming(take(4_usize))(b)?;
                     Ok((b, PgsqlBEMessage::AuthenticationMD5Password(
                                 AuthenticationMessage {
@@ -751,11 +750,11 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
                 9 => Ok((b, PgsqlBEMessage::AuthenticationSSPI(
                             AuthenticationMessage {
                                 identifier,
                                 length,
                                 auth_type,
-                                payload: payload.to_vec(),
+                                payload: b.to_vec(),
                             }))),
                 // TODO - For SASL, should we parse specific details of the challenge itself? (as seen in: https://github.com/launchbadge/sqlx/blob/master/sqlx-core/src/postgres/message/authentication.rs )
                 10 => {
                     let (b, auth_mechanisms) = parse_sasl_mechanisms(b)?;
                     Ok((b, PgsqlBEMessage::AuthenticationSASL(
@@ -765,27 +764,25 @@ fn pgsql_parse_authentication_message<'a>(i: &'a [u8]) -> IResult<&'a [u8], Pgsq
                                     auth_type,
                                     auth_mechanisms,
                                 })))
                 }
                 11 => {
-                    let (b, sasl_challenge) = rest(i)?;
                     Ok((b, PgsqlBEMessage::AuthenticationSASLContinue(
                                 AuthenticationMessage {
                                     identifier,
                                     length,
                                     auth_type,
-                                    payload: sasl_challenge.to_vec(),
+                                    payload: b.to_vec(),
                                 })))
                 },
                 12 => {
-                    let (i, signature) = take(length - 8)(i)?;
-                    Ok((i, PgsqlBEMessage::AuthenticationSASLFinal(
+                    Ok((b, PgsqlBEMessage::AuthenticationSASLFinal(
                                 AuthenticationMessage {
                                     identifier,
                                     length,
                                     auth_type,
-                                    payload: signature.to_vec(),
+                                    payload: b.to_vec(),
                                 }
                                 )))
                 }
                 // TODO add other authentication messages
                 _ => return Err(Err::Error(make_error(i, ErrorKind::Switch))),

Vulnerable code:     let (i, payload) = peek(rest)(i)?;
                                payload: payload.to_vec(),
                                payload: payload.to_vec(),
                                payload: payload.to_vec(),
                    let (b, sasl_challenge) = rest(i)?;
                                    payload: sasl_challenge.to_vec(),
                    let (i, signature) = take(length - 8)(i)?;
                    Ok((i, PgsqlBEMessage::AuthenticationSASLFinal(
                                    payload: signature.to_vec(),
Fixed code:                                 payload: b.to_vec(),
                                payload: b.to_vec(),
                                payload: b.to_vec(),
                                    payload: b.to_vec(),
                    Ok((b, PgsqlBEMessage::AuthenticationSASLFinal(
                                    payload: b.to_vec(),