{"record":{"id":"93a5114307d03fb1","repo":"shadow1ng/fscan","slug":"kafka-response-too-large-d","errorCode":null,"errorMessage":"kafka response too large: %d","messagePattern":"kafka response too large: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/kafka.go","lineNumber":194,"sourceCode":"\tcopy(buf[14:], clientID)\n\tcopy(buf[14+len(clientID):], body)\n\n\t_, err := conn.Write(buf)\n\treturn err\n}\n\nfunc kafkaRecv(conn io.Reader) ([]byte, error) {\n\t// 读取 4 字节长度\n\tlenBuf := make([]byte, 4)\n\tif _, err := io.ReadFull(conn, lenBuf); err != nil {\n\t\treturn nil, err\n\t}\n\tmsgLen := int(binary.BigEndian.Uint32(lenBuf))\n\tif msgLen < 4 {\n\t\treturn nil, fmt.Errorf(\"invalid kafka response length: %d\", msgLen)\n\t}\n\tif msgLen > maxKafkaResponseSize {\n\t\treturn nil, fmt.Errorf(\"kafka response too large: %d\", msgLen)\n\t}\n\t// 读取消息体\n\tmsg := make([]byte, msgLen)\n\tif _, err := io.ReadFull(conn, msg); err != nil {\n\t\treturn nil, err\n\t}\n\t// 跳过 correlation_id (4B)，返回 body\n\treturn msg[4:], nil\n}\n\nfunc kafkaString(s string) []byte {\n\tb := []byte(s)\n\tbuf := make([]byte, 2+len(b))\n\tbinary.BigEndian.PutUint16(buf, uint16(len(b)))\n\tcopy(buf[2:], b)\n\treturn buf\n}\n","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/kafka.go#L176-L212","documentation":"kafkaRecv rejects a declared response length exceeding maxKafkaResponseSize to prevent unbounded memory allocation from hostile or desynced responses. msg := make([]byte, msgLen) would otherwise allocate attacker-controlled memory. This is a defensive DoS guard on the framing parser.","triggerScenarios":"kafkaRecv (called by doKafkaAuth, identifyService, tests): the 4-byte length prefix decodes to a value greater than maxKafkaResponseSize — desynced stream reading a payload as a length, a malicious peer, or a genuinely oversized response the limit doesn't accommodate.","commonSituations":"Stream misalignment after an earlier short read causing payload bytes to be interpreted as a length prefix; scanning a honeypot/service that sends huge random frames; maxKafkaResponseSize set too low for brokers returning large Metadata responses (many topics).","solutions":["If legitimate large Metadata responses hit the limit, raise maxKafkaResponseSize appropriately","Reconnect on this error — the stream is almost certainly desynced and unrecoverable","Verify framing alignment after every read; never continue reading after a size rejection","Use io.LimitReader-style allocation caps even if the limit is raised"],"exampleFix":"// before\nif msgLen > maxKafkaResponseSize {\n    return nil, fmt.Errorf(\"kafka response too large: %d\", msgLen)\n}\n// after\nif msgLen > maxKafkaResponseSize {\n    return nil, fmt.Errorf(\"kafka response too large: %d (limit %d); stream likely desynced, reconnect required\", msgLen, maxKafkaResponseSize)\n}","handlingStrategy":"type-guard","validationCode":"// Cap accepted frame size at the same constant used by the parser\nconst expectedMax = maxKafkaResponseSize\n// ensure your broker's Metadata responses (topic count) stay well under expectedMax","typeGuard":"func isPlausibleKafkaLen(lenBuf []byte) bool {\n    l := binary.BigEndian.Uint32(lenBuf)\n    return l >= 4 && l <= maxKafkaResponseSize\n}","tryCatchPattern":"resp, err := kafkaRecv(conn)\nif err != nil {\n    if strings.Contains(err.Error(), \"kafka response too large\") {\n        log.Println(\"oversized kafka frame; stream desynced or hostile peer — reconnect\")\n        return\n    }\n    return err\n}","preventionTips":["Always reconnect after a size-limit rejection; the stream is unrecoverable","Raise maxKafkaResponseSize only if legitimate large Metadata responses require it","Prefer bounded allocation (io.LimitReader) over trusting the length prefix outright","Treat huge frames from unknown peers as a scanning honeypot signal"],"tags":["kafka","protocol","framing","dos-protection","validation"],"backgroundTag":"payload-too-large","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}