Skip to content

fix(statsd source): [OBE-10714] avoid panic on non-char-boundary gauge value slice - #147

Open
piyush-s15 wants to merge 1 commit into
masterfrom
obe-10714-statsd-gauge-panic
Open

fix(statsd source): [OBE-10714] avoid panic on non-char-boundary gauge value slice#147
piyush-s15 wants to merge 1 commit into
masterfrom
obe-10714-statsd-gauge-panic

Conversation

@piyush-s15

Copy link
Copy Markdown
Contributor

What

Parser::parse's "g" (gauge) branch stripped a leading sign character with a byte-index slice
(parts[0][1..]) after checking only whether the first character was an ASCII digit. Any gauge
value beginning with a multi-byte UTF-8 character (e.g. ±) made that slice land inside the
character's bytes and panic (byte index 1 is not a char boundary). Fixed by replacing it with
str::get(1..), which returns None (→ ParseError::Malformed) instead of panicking when the
offset isn't on a char boundary.

Why

In UDP mode (the default statsd source config) this panic propagates through handle_errors's
catch_unwind (topology/mod.rs:59-74) to abort_tx (topology/running.rs:984-985) to a full
Vector process shutdown via SignalTo::Shutdown — a single unauthenticated UDP datagram (e.g.
x:\xc2\xb11|g) took down every pipeline sharing the process. CVSS 8.7 (High).

How to Test

  1. cargo test --lib sources::statsd::parser::test::gauge_with_multibyte_prefix_does_not_panic
    RED pre-fix (panics), GREEN post-fix.
  2. make test SCOPE=sources::statsd — 20/20 passing.
  3. Manual: send printf 'x:\xc2\xb11|g' | nc -u -w0 <host> 8125 to a statsd UDP source — process
    no longer crashes.

Ticket

Ticket Severity Location Scanner recheck
OBE-10714 High (CVSS 8.7) src/sources/statsd/parser.rs:97 No automated SAST tool filed this (AI-based security review finding, no re-runnable rule id) — closure verified by code-review + security-scan + closure-verification passes, corroborated by cargo clippy (clean) and cargo test (20/20, including a negative test for the exact exploit input).

Jira: https://sentinelone.atlassian.net/browse/OBE-10714

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

…slice

Parser::parse's "g" (gauge) branch stripped a leading sign character with
a byte-index slice (parts[0][1..]) after checking only whether the first
*character* was an ASCII digit. Any gauge value beginning with a
multi-byte UTF-8 character (e.g. `±`) made that slice land inside the
character's bytes, panicking with "byte index 1 is not a char boundary".

In UDP mode (the default statsd config) this panic propagates through
handle_errors's catch_unwind to abort_tx to a full Vector process
shutdown, so a single unauthenticated UDP datagram (e.g. `x:\xc2\xb11|g`)
took down every pipeline sharing the process.

Replace the byte-index slice with str::get(1..), which returns None
(=> ParseError::Malformed) instead of panicking when the offset isn't on
a char boundary. The existing StatsdDeserializer/statsd_udp error paths
already handle Malformed without aborting the source, so no other files
need to change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants