From 7415a560dcd1a3c9ed1c28165b86c11317240818 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:34:25 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20Bound=20wyo?= =?UTF-8?q?ming=20payload=5Flength=20to=20prevent=20DoS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: mARTin-B78 <91568406+mARTin-B78@users.noreply.github.com> --- linux/blitztext/wakeword.py | 5 +++++ linux/blitztext/wakeword_bench.py | 7 +++++++ linux/tests/test_wakeword_security.py | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 linux/tests/test_wakeword_security.py diff --git a/linux/blitztext/wakeword.py b/linux/blitztext/wakeword.py index b1283f3..e7b4877 100644 --- a/linux/blitztext/wakeword.py +++ b/linux/blitztext/wakeword.py @@ -112,6 +112,11 @@ class WakewordListener: self._handle_detection() payload_len = msg.get("payload_length", 0) + + if not isinstance(payload_len, int) or payload_len < 0 or payload_len > 1048576: + logbuffer.log(f"[wakeword] Invalid payload_length: {payload_len}") + break + if payload_len > 0: # Consume payload remaining = payload_len diff --git a/linux/blitztext/wakeword_bench.py b/linux/blitztext/wakeword_bench.py index eba7057..04f8b0a 100644 --- a/linux/blitztext/wakeword_bench.py +++ b/linux/blitztext/wakeword_bench.py @@ -322,6 +322,13 @@ def _drain_detections(buf: bytes) -> tuple[bytes, int]: except (ValueError, UnicodeDecodeError): return rest, found plen = msg.get("payload_length", 0) or 0 + if not isinstance(plen, int): + raise ValueError(f"Invalid payload_length type: {type(plen)}") + if plen < 0: + raise ValueError(f"Negative payload_length: {plen}") + if plen > 1048576: # 1MB limit to prevent DoS via unbounded reads + raise ValueError(f"Unreasonably large payload_length: {plen}") + if len(rest) < plen: return buf, found # payload not fully arrived yet; wait for more rest = rest[plen:] diff --git a/linux/tests/test_wakeword_security.py b/linux/tests/test_wakeword_security.py new file mode 100644 index 0000000..d123d49 --- /dev/null +++ b/linux/tests/test_wakeword_security.py @@ -0,0 +1,23 @@ +import json +import pytest + +from blitztext.wakeword_bench import _drain_detections + +def test_drain_detections_payload_length_validation(): + # Test massive payload length + msg = {"type": "info", "payload_length": 1048577} + buf = json.dumps(msg).encode("utf-8") + b"\n" + with pytest.raises(ValueError, match="Unreasonably large payload_length"): + _drain_detections(buf) + + # Test negative payload length + msg = {"type": "info", "payload_length": -1} + buf = json.dumps(msg).encode("utf-8") + b"\n" + with pytest.raises(ValueError, match="Negative payload_length"): + _drain_detections(buf) + + # Test invalid type for payload length + msg = {"type": "info", "payload_length": "invalid"} + buf = json.dumps(msg).encode("utf-8") + b"\n" + with pytest.raises(ValueError, match="Invalid payload_length type"): + _drain_detections(buf)