{"record":{"id":"981f1b1f132cb3e8","repo":"stamparm/maltrail","slug":"packet-too-short-for-header-protection-sample","errorCode":null,"errorMessage":"packet too short for header-protection sample","messagePattern":"packet too short for header-protection sample","errorType":"exception","errorClass":"QuicParseError","httpStatus":null,"severity":"warning","filePath":"core/quic_sni.py","lineNumber":288,"sourceCode":"    off = 5\n    dcid_len = p[off]; off += 1\n    dcid = bytes(udp_payload[off:off + dcid_len]); off += dcid_len\n    scid_len = p[off]; off += 1\n    off += scid_len\n    # long header packet type must be Initial\n    if ver_kind == 1:\n        if (first & 0x30) != 0x00:\n            return None\n    else:\n        if (first & 0x30) != 0x10:                            # v2 remaps Initial to 0b01\n            return None\n    token_len, off = _read_varint(udp_payload, off)\n    off += token_len\n    length, off = _read_varint(udp_payload, off)             # length of (pn + payload)\n    pn_offset = off\n    sample_offset = pn_offset + 4\n    if sample_offset + 16 > len(p):\n        raise QuicParseError(\"packet too short for header-protection sample\")\n\n    key, iv, hp = derive_client_initial_keys(dcid, ver_kind)\n\n    sample = bytes(udp_payload[sample_offset:sample_offset + 16])\n    mask = _b(aes_ecb_block(hp, sample))\n\n    first_unmasked = first ^ (mask[0] & 0x0F)\n    pn_len = (first_unmasked & 0x03) + 1\n    pn_bytes = bytearray(udp_payload[pn_offset:pn_offset + pn_len])\n    for i in range(pn_len):\n        pn_bytes[i] ^= mask[1 + i]\n    packet_number = 0\n    for bb in pn_bytes:\n        packet_number = (packet_number << 8) | bb\n\n    payload_offset = pn_offset + pn_len\n    payload_len = length - pn_len\n    ciphertext = bytes(udp_payload[payload_offset:payload_offset + payload_len])","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/core/quic_sni.py#L270-L306","documentation":"During QUIC Initial SNI extraction, the code needs a 16-byte header-protection sample starting at sample_offset (packet-number offset + 4). The packet's payload `p` is too short to supply those 16 bytes, so _extract_sni_impl raises QuicParseError.","triggerScenarios":"UDP payload shorter than the required varint-decoded offsets allow; coalesced/fragmented packets; crafted or corrupt QUIC Initial packets; non-Initial packets routed into the parser.","commonSituations":"Capturing truncated packets (snapshot length too small in tcpdump), feeding TCP-reassembled or padded junk into extract_sni_from_quic_initial, fuzz/malicious traffic.","solutions":["Increase capture snapshot size (e.g. tcpdump -s0) so UDP payloads aren't truncated","Catch QuicParseError in extract_sni_from_quic_initial callers and skip the packet","Check length bounds after reading each varint before computing sample_offset","Filter to only valid QUIC Initial long-header packets before parsing"],"exampleFix":"// before\nsni = extract_sni_from_quic_initial(udp_payload)\n// after\ntry:\n    sni = extract_sni_from_quic_initial(udp_payload)\nexcept QuicParseError:\n    sni = None  # malformed/short packet","handlingStrategy":"try-catch","validationCode":"def quic_initial_plausible(udp_payload):\n    return udp_payload and len(udp_payload) > 6 and (udp_payload[0] & 0x80) and len(udp_payload) >= 1200  # typical Initial size","typeGuard":null,"tryCatchPattern":"try:\n    sni = extract_sni_from_quic_initial(payload)\nexcept QuicParseError:\n    sni = None  # skip malformed packet","preventionTips":["Capture with full snapshot length (-s0) to avoid truncated payloads","Filter to long-header Initial packets before parsing","Bounds-check each varint read when extending the parser","Fuzz-test the parser against short/corrupt packets"],"tags":["python","quic","packet-parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}