Skip to content

Security: NSEC _read_bitmap does not bound bitmap_length against the record end #1725

@bluetoothbot

Description

@bluetoothbot

Problem

_read_bitmap(end) reads an attacker-controlled bitmap_length byte and then unconditionally does self.offset += 2 + bitmap_length, with no check that offset_plus_two + bitmap_length <= end. Because Python slicing is forgiving, the inner self.data[offset_plus_two:bitmap_end] does not raise even when bitmap_end overshoots — it simply consumes adjacent bytes (the next record's header) as bitmap data and then leaves self.offset past the NSEC record's declared end. _read_others only resets self.offset = end in the exception path, so a malformed-but-non-throwing NSEC silently corrupts the parse offset for every subsequent record in the same packet, and the bitmap window/byte arithmetic can convert two random adjacent bytes into hundreds of rdtypes entries that get cached on the resulting DNSNsec.

Why This Matters

Single-packet impact only (record-boundary confusion + a few KB of synthesized rdtypes cached as long as the NSEC stays in the DNSCache), but it lets a malicious LAN peer suppress legitimate records in a packet (subsequent records fail to parse or are skipped) and pollute the NSEC cache with attacker-chosen "absent" type bits. That second effect can be used to talk an AddressResolver out of issuing follow-up queries for a real host, since NSEC negative answers gate that decision.

Suggested Fix

After reading bitmap_length, clamp / validate against end: if offset_plus_two + bitmap_length > end: raise IncomingDecodeError(...). Also validate window < 256 (it already fits in a byte) and bound the total rdtypes length so a 255-byte window can't compose with multiple windows to bloat the in-memory cached record.

Details

Severity 🟡 Medium
Category memory_safety
Location src/zeroconf/_protocol/incoming.py:383-399
Effort ⚡ Quick fix

🤖 Created by Kōan from audit session

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions