]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: urilen keyword fails on trailing junk
authorPhilippe Antoine <pantoine@oisf.net>
Mon, 27 Oct 2025 19:37:57 +0000 (20:37 +0100)
committerVictor Julien <vjulien@oisf.net>
Wed, 29 Oct 2025 15:33:53 +0000 (15:33 +0000)
Fails especailly on 1<>2 which looks like a range, but is invalid
as too small, and ended up being accepted as =1

Ticket: 8028

rust/src/detect/uri.rs

index 0b438447388023fa9322684908abc45823e7d00e..6584d5d373ad9f367e8de615edaae26e371de864 100644 (file)
@@ -17,9 +17,9 @@
 
 use super::uint::*;
 use nom7::branch::alt;
-use nom7::bytes::complete::{is_a, tag};
+use nom7::bytes::complete::{is_a, tag, take_while};
 use nom7::character::complete::char;
-use nom7::combinator::{opt, value};
+use nom7::combinator::{all_consuming, opt, value};
 use nom7::IResult;
 
 use std::ffi::CStr;
@@ -35,26 +35,25 @@ pub fn detect_parse_urilen_raw(i: &str) -> IResult<&str, bool> {
     let (i, _) = opt(is_a(" "))(i)?;
     let (i, _) = char(',')(i)?;
     let (i, _) = opt(is_a(" "))(i)?;
-    return alt((value(true, tag("raw")), value(false, tag("norm"))))(i);
+    let (i, v) = alt((value(true, tag("raw")), value(false, tag("norm"))))(i)?;
+    let (i, _) = opt(is_a(" "))(i)?;
+    Ok((i, v))
 }
 
 pub fn detect_parse_urilen(i: &str) -> IResult<&str, DetectUrilenData> {
     let (i, du16) = detect_parse_uint_notending::<u16>(i)?;
-    let (i, raw) = opt(detect_parse_urilen_raw)(i)?;
-    match raw {
-        Some(raw_buffer) => {
-            return Ok((i, DetectUrilenData { du16, raw_buffer }));
-        }
-        None => {
-            return Ok((
-                i,
-                DetectUrilenData {
-                    du16,
-                    raw_buffer: false,
-                },
-            ));
-        }
+    let (i, _) = take_while(|c| c == ' ')(i)?;
+    if i.is_empty() {
+        return Ok((
+            i,
+            DetectUrilenData {
+                du16,
+                raw_buffer: false,
+            },
+        ));
     }
+    let (i, raw_buffer) = all_consuming(detect_parse_urilen_raw)(i)?;
+    return Ok((i, DetectUrilenData { du16, raw_buffer }));
 }
 
 #[no_mangle]
@@ -76,3 +75,17 @@ pub unsafe extern "C" fn SCDetectUrilenFree(ctx: &mut DetectUrilenData) {
     // Just unbox...
     std::mem::drop(Box::from_raw(ctx));
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_parse_urilen() {
+        let (_, ctx) = detect_parse_urilen("1<>3").unwrap();
+        assert_eq!(ctx.du16.arg1, 1);
+        assert_eq!(ctx.du16.arg2, 3);
+        assert_eq!(ctx.du16.mode, DetectUintMode::DetectUintModeRange);
+        assert!(detect_parse_urilen("1<>2").is_err());
+    }
+}