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)