fix(security): prevent 9 panic/OOM vectors in VRL runtime (batch J) - #7
Open
JuanMantica45 wants to merge 1 commit into
Open
fix(security): prevent 9 panic/OOM vectors in VRL runtime (batch J)#7JuanMantica45 wants to merge 1 commit into
JuanMantica45 wants to merge 1 commit into
Conversation
….10743 batch J)
Close all panics and DoS-by-OOM paths identified in the batch-J security audit:
- OBE-10722 find(): clamp negative `from` to 0 before usize cast; guard
find_regex_in_str against offset > haystack.len() (regex::find_at panic).
- OBE-10723 format_number(): replace .expect("not NaN") with fallible
Decimal::from_f64 conversion; returns VRL error for ±∞ and out-of-range floats.
- OBE-10724 format_number(): reject negative scale; cap scale at 1024 to prevent
unbounded push('0') OOM loop; type_def changed to fallible().
- OBE-10727 arithmetic: add safe_mul/safe_add/safe_rem helpers mirroring safe_sub;
replace NotNan::mul/add/rem calls that panic on NaN result (e.g. ∞ * 0).
- OBE-10731 parse_xml(): filter single-child path to element/text nodes; prevents
Comment/PI child from reaching the unreachable!() arm in process_node.
- OBE-10733 starts_with(): fix hand-rolled Chars iterator — treat width==0 (stray
continuation bytes) and truncated multi-byte sequences as error bytes; fix
off-by-one in the Err arm that read past the advanced pos.
- OBE-10734 lex.rs: add b'}' => '}' arm to unescape_string_literal; the lexer
already accepted \} via escape_code but the unescaper had no matching arm,
hitting unimplemented!().
- OBE-10735 array insert: cap insert_value index at ±32768 to bound Null-padding
loop; cap Vec::with_capacity in crud/insert.rs to the same limit.
- OBE-10743 parse_grok(): wrap pattern.match_against in catch_unwind to convert
Oniguruma retry-limit panics to VRL errors (mirrors existing parse_groks guard).
All 1680 lib tests pass. New regression tests added for each fixed panic path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes OBE-10722, OBE-10723, OBE-10724, OBE-10727, OBE-10731, OBE-10733, OBE-10734, OBE-10735, OBE-10743.
Batch J of the security audit identified 9 exploitable panic/DoS paths in the VRL runtime, all reachable from untrusted event data or operator-authored programs. This PR fixes all of them with minimal surgical changes.
stdlib/find.rsfromwraps tousize::MAX→regex::find_atpanics whenoffset > haystack.len()from.max(0)before cast; add bounds check infind_regex_in_strstdlib/format_number.rsDecimal::from_f64(*v).expect("not NaN")panics on ±∞ and floats > 7.9e28 (NotNanpermits ∞).ok_or_else(...)?returning a VRL errorstdlib/format_number.rsscale: i64 as usize+ unboundedpush('0')loop → OOM for large/negative scaletype_deftofallible()compiler/value/arithmetic.rsNotNan::mul/add/rempanic when result is NaN (e.g.∞ * 0,∞ + -∞,∞ % ∞);try_subwas already fixed (#1186) but mul/add/rem were notsafe_mul,safe_add,safe_remmirroring the existingsafe_subpatternparsing/xml.rsnode.children().next()without filtering; a Comment/PI child reachesprocess_node→_ => unreachable!()stdlib/starts_with.rsChars::nextusesutf8_width::get_widthreturning 0 for stray bytes → slice of length 0 →from_utf8("") = Ok→"".chars().next() = None→.unwrap()panicswidth == 0and truncated sequences as error bytes; fix off-by-one inErrarmparser/lex.rsescape_codeaccepts\}butunescape_string_literalhas nob'}'arm → hitsunimplemented!()b'}' => '}'armvalue/value/crud/mod.rs+insert.rsinsert_valuepads withValue::Nullup to arbitrary index with no cap → OOM;Vec::with_capacity(index+1)also uncappedwith_capacityto the same limitstdlib/parse_grok.rspattern.match_againstuses externalgrokcrate whose Oniguruma regex engine panics on retry-limit exhaustion;parse_grokshascatch_unwindbutparse_grok(singular) does notmatch_againstinstd::panic::catch_unwind; return VRL error onErrTest plan
cargo test --lib: 1680 passed, 0 failed (was 1671 before new tests)🤖 Generated with Claude Code