elastic / elastic/beats

[packetbeat-parser-safety] Cassandra prepared-result pkeyCount can trigger makeslice panic in parseResultMetadata

Open
#52,407 1 comment 0 reactions 0 assignees View on GitHub
needs_team
Dominant language
Go
Stars
12.7k
Forks
5k
Avg merge
2d 15m
Merged PRs (30d)
385

Description

## Findings

### 1. Cassandra prepared-result metadata trusts unbounded `pkeyCount` and panics

**Location**
- `packetbeat/protos/cassandra/internal/gocql/frame.go:385-391`
- `packetbeat/protos/cassandra/internal/gocql/frame.go:171-185`
- `packetbeat/protos/cassandra/internal/gocql/frame.go:456-467`

**Evidence**
At `packetbeat/protos/cassandra/internal/gocql/frame.go:389` the parser allocates directly from a packet-derived count with no bounds validation:

```go
pkeyCount := decoder.ReadInt()
pkeys := make([]int, pkeyCount)
for i := 0; i < pkeyCount; i++ {
pkeys[i] = int(decoder.ReadShort())
}
```

`pkeyCount` is read from untrusted frame bytes (`decoder.ReadInt()`), and this code is reached on `RESULT kind=prepared` via `parseResultPrepared()` (`frame.go:456-467`). A malformed response can set `pkeyCount` negative or huge, causing a runtime `makeslice` panic. `Framer.ReadFrame()` re-panics `runtime.Error` (`frame.go:179-180`), so this is a process-crashing path, not a handled parse error.

**Why this is wrong**
A network peer controls Cassandra response bytes. Using packet-derived counts as allocation sizes without validating range violates parser bounds safety and allows malformed/truncated traffic to crash Packetbeat.

**Impact**
High severity denial-of-service: a malicious or buggy Cassandra server (or any man-in-the-middle/fuzzed traffic source in capture path) can crash packet processing by sending a malformed prepared-result metadata section.

**Suggested fix**
Add explicit bounds checks before allocation and before iterating:

```go
if pkeyCount < 0 || pkeyCount > maxReasonablePKeyCount {
panic(fmt.Errorf("invalid pkeyCount: %d", pkeyCount))
}
```

Use a limit derived from remaining frame bytes (e.g., `remaining/2`) and reject impossible values before `make`.

## Reproducer test (currently panics)

The following test demonstrates the panic today by supplying `pkeyCount = -1`:

```go
func TestParseResultMetadata_NegativePkeyCountDoesNotPanic(t *testing.T) {
raw := []byte{
0x00, 0x00, 0x00, 0x00, // flags
0x00, 0x00, 0x00, 0x00, // colCount
0xff, 0xff, 0xff, 0xff, // pkeyCount = -1
}
decoder := &ByteArrayDecoder{Data: &raw}
f := &Framer{decoder: decoder, proto: protoVersion4}

// Desired behavior: handled parser error, not panic.
require.NotPanics(t, func() {
_ = f.parseResultMetadata(true)
})
}
```

Run with:

```bash
go test ./packetbeat/protos/cassandra/internal/gocql -run TestParseResultMetadata_NegativePkeyCountDoesNotPanic -count=1
```

## Unsafe-location checklist from this sweep

- [ ] `packetbeat/protos/cassandra/internal/gocql/frame.go:389` — validate `pkeyCount` before `make([]int, pkeyCount)` and loop.

## Coverage checked and found clean for this run

Inspected parser families for this bug class (high-severity panic/infinite-loop/overflow paths): `amqp`, `dhcpv4`, `dns`, `http`, `icmp`, `memcache`, `mongodb`, `mysql`, `nfs`, `pgsql`, `redis`, `sip`, `thrift`, `tls`; no additional distinct high-severity findings survived verification in this pass.

---
[What is this?](https://ela.st/github-ai-tools) | [From workflow: Sweeper: Packetbeat Parser Bounds Safety](https://github.com/elastic/beats/actions/runs/30805255066)

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.
> - [x] expires on Aug 10, 2026, 10:35 AM UTC

Contributor guide

Open the contributing guide

Research direction

Start in packetbeat/protos/cassandra/internal/gocql/frame.go, reading parseResultMetadata and the prepared-result path in parseResultPrepared, then run the provided focused Go test command. Use the existing negative-pkeyCount reproducer as the baseline; done means malformed metadata is handled without a panic and the focused test passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, networking, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.