zeta12ti / parse_duration

Parses a duration from a string.
MIT License
17 stars 2 forks source link

Add exponent check #18

Closed MakotoE closed 2 years ago

MakotoE commented 4 years ago

This changes parse() to quickly return an error if the exponent is very large. It addresses a potential denial-of-service vulnerability.

I did a fuzz test and found a string that can cause it to hang. This case timed out after 1785 seconds.

parse("5e6666666666663S")

Doing parse("1e1000000s"), the highest possible exponent as a result of this change, takes 180 milliseconds on an optimized build. Adding another zero takes 6 seconds.

#[test]
fn test() { // Tested like this
    let start = std::time::Instant::now();
    parse("1e1000000s").unwrap_err();
    let time: std::time::Duration = std::time::Instant::now() - start;
    println!("{}", time.as_millis());
}
// cargo test --package parse_duration --lib --release -- tests::test --exact --nocapture
mverleg commented 2 years ago

Nice find and great to have this fix!

But I think 180ms is far too long for most applications. If I'm not mistaken, the age of the universe is about 1e20 seconds, so do we really need 1e1000000?

MakotoE commented 2 years ago

I'm closing this PR because the suggestions in the linked issue are better.