[packetbeat-parser-safety] AMQP field table parsing panics on truncated and overflowed byte-array fields
- Dominant language
- Go
- Stars
- 12.7k
- Forks
- 5k
- Avg merge
- 2d 15m
- Merged PRs (30d)
- 385
Description
## Findings
Two **confirmed panic** bugs were found in `packetbeat/protos/amqp/amqp_fields.go` and reproduced with crafted wire-plausible AMQP field-table payloads.
### 1) Truncated field-table entry panics on missing type byte
**Location:** `packetbeat/protos/amqp/amqp_fields.go:127` (inside `fieldUnmarshal`)
**Unsafe expression:** `switch data[offset] {`
**Controlling packet field:** field-table entry name length (shortstr length byte) within AMQP method arguments (attacker-controlled).
**What is wrong:** when table payload has a zero-length name but no following type byte, `offset` is advanced to `len(data)` and then `data[offset]` is indexed, causing `panic: index out of range`.
**Why it matters:** malformed/truncated AMQP packets from a peer can crash Packetbeat parser goroutine (DoS).
**One-line fix:** add bounds guard before dereference, e.g. `if int(offset) >= len(data) { return true }`.
### 2) `byteArray` length arithmetic can overflow before bounds check
**Location:** `packetbeat/protos/amqp/amqp_fields.go:279,283,284`
**Unsafe expressions:**
- `len(data) < int(offset+5+size)`
- `data[offset+5 : offset+5+size]`
- `offset += 5 + size`
**Controlling packet field:** `byteArray` `size` (`uint32`) parsed from packet bytes.
**What is wrong:** `offset+5+size` uses `uint32` arithmetic and can wrap before conversion/check, allowing a wrapped bound check and then invalid slice bounds panic.
**Why it matters:** hostile/malformed AMQP field tables can trigger parser panic via integer overflow.
**One-line fix:** perform overflow-safe checks before addition, e.g. validate `offset+5 >= offset` and `size <= uint32(len(data))-(offset+5)` before slicing.
## Reproducer tests (confirmed panics today)
Paste into `packetbeat/protos/amqp/amqp_test.go` and run `go test ./packetbeat/protos/amqp -run 'TestTmp_FieldUnmarshal(MissingTypePanics|ByteArrayOverflowPanics)$'`.
```go
func TestTmp_FieldUnmarshalMissingTypePanics(t *testing.T) {
fields := mapstr.M{}
data := []byte{0x00, 0x00, 0x00, 0x01, 0x00} // table len=1, empty name, missing type
assert.Panics(t, func() {
_, _, _ = getTable(fields, data, 0)
})
}
func TestTmp_FieldUnmarshalByteArrayOverflowPanics(t *testing.T) {
fields := mapstr.M{}
data := []byte{
0x00, 0x00, 0x00, 0x06, // table length = 6
0x00, // empty field name
byte(byteArray),
0xFF, 0xFF, 0xFF, 0xFE, // huge size -> overflow in offset+5+size
}
assert.Panics(t, func() {
_, _, _ = getTable(fields, data, 0)
})
}
```
## Unsafe locations checklist (grouped by parser)
### AMQP (`packetbeat/protos/amqp`)
- [ ] `amqp_fields.go:127` — `data[offset]` in `fieldUnmarshal` without `offset < len(data)` guard after name parsing.
- [ ] `amqp_fields.go:279,283,284` — `offset+5+size` overflow risk in `byteArray` case before slicing/advancing offset.
## Coverage notes (inspected and no high-severity findings confirmed)
Checked parser safety paths in: `http`, `sip`, `mysql`, `pgsql`, `mongodb`, `thrift`, `tls`, `nfs`, plus AMQP parser/header helpers. No additional verified high-severity panic/loop/overflow issues survived verification.
> [!NOTE]
>
> 🔒 Integrity filtering filtered 1 item
>
> Integrity filtering activated and filtered the following item during workflow execution.
> This happens when a tool call accesses a resource that does not meet the required integrity or secrecy level of the workflow.
>
> - issue:elastic/beats#unknown (`search_issues`: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".)
>
>
---
[What is this?](https://ela.st/github-ai-tools) | [From workflow: Sweeper: Packetbeat Parser Bounds Safety](https://github.com/elastic/beats/actions/runs/23738175276)
Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.
> - [x] expires on Apr 6, 2026, 9:54 AM UTC
Contributor guide
Research direction
Start with packetbeat/protos/amqp/amqp_fields.go at fieldUnmarshal and the byteArray case, then run the two named reproducer tests in packetbeat/protos/amqp/amqp_test.go with the provided go test command. Done means truncated and oversized AMQP field-table inputs return safely without panicking, with regression coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- Half a day
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100