elastic / elastic/beats

[packetbeat-parser-safety] AMQP field table parsing panics on truncated and overflowed byte-array fields

Open Beginner friendly
#49,767 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

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.