{"record":{"id":"7cc373bddf31725a","repo":"shadow1ng/fscan","slug":"invalid-fragment-size-d","errorCode":null,"errorMessage":"invalid fragment size: %d","messagePattern":"invalid fragment size: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/nfs.go","lineNumber":232,"sourceCode":"\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\toffset += int(pad)\n\t\t\t}\n\t\t}\n\t}\n\treturn exports\n}\n\nfunc readRPCFragment(conn interface {\n\tRead([]byte) (int, error)\n}, maxPayload int) ([]byte, error) {\n\tvar header [4]byte\n\tif _, err := io.ReadFull(conn, header[:]); err != nil {\n\t\treturn nil, fmt.Errorf(\"short fragment header: %w\", err)\n\t}\n\tsize := int(binary.BigEndian.Uint32(header[:]) & 0x7fffffff)\n\tif size <= 0 || size > maxPayload {\n\t\treturn nil, fmt.Errorf(\"invalid fragment size: %d\", size)\n\t}\n\tpayload := make([]byte, size)\n\tif _, err := io.ReadFull(conn, payload); err != nil {\n\t\treturn nil, fmt.Errorf(\"short fragment payload: %w\", err)\n\t}\n\treturn payload, nil\n}\n\nfunc (p *NFSPlugin) buildRPCCall(xid, program, version, procedure uint32, data []byte) []byte {\n\tauthNone := []byte{0, 0, 0, 0, 0, 0, 0, 0} // AUTH_NONE flavor=0, len=0\n\n\tbuf := make([]byte, 0, 40+len(data))\n\tbuf = binary.BigEndian.AppendUint32(buf, xid)\n\tbuf = binary.BigEndian.AppendUint32(buf, 0) // CALL\n\tbuf = binary.BigEndian.AppendUint32(buf, 2) // RPC version\n\tbuf = binary.BigEndian.AppendUint32(buf, program)\n\tbuf = binary.BigEndian.AppendUint32(buf, version)\n\tbuf = binary.BigEndian.AppendUint32(buf, procedure)","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/nfs.go#L214-L250","documentation":"readRPCFragment reads one Record Marking fragment from an NFS/RPC TCP stream. The 4-byte header's high bit is stripped (last-fragment flag) and the remaining 31 bits must yield a size in (0, maxPayload]. This error is thrown when the peer announces a fragment that is zero or larger than the maximum allowed payload, i.e. a malformed or hostile stream header.","triggerScenarios":"Calling rpcNullCall or getExports against a server that sends a fragment header with size 0 (after masking) or exceeding maxPayload; test TestNFSReadRPCFragmentRejectsInvalidSize exercises this directly.","commonSituations":"Scanning a port that is not really NFS/mountd so random bytes are parsed as a fragment header; a middlebox/proxy corrupting the record-marking protocol; a malicious honeypot service returning oversized sizes.","solutions":["Verify the target is actually an NFS server exposing the RPC protocol on the expected port","Check that no proxy/NAT device is mangling the TCP stream between scanner and server","Capture traffic and compare the first 4 bytes against RFC 5531 record-marking framing","If intentional, raise maxPayload only after confirming the peer is trusted"],"exampleFix":"// before\nsize := int(binary.BigEndian.Uint32(header[:]) & 0x7fffffff)\n// after\nsize := int(binary.BigEndian.Uint32(header[:]) & 0x7fffffff)\nif size <= 0 || size > maxPayload {\n    return nil, fmt.Errorf(\"invalid fragment size: %d (max %d)\", size, maxPayload) // clearer diagnostics\n}","handlingStrategy":"validation","validationCode":"func validFragmentSize(hdr [4]byte, maxPayload int) bool {\n    size := int(binary.BigEndian.Uint32(hdr[:]) & 0x7fffffff)\n    return size > 0 && size <= maxPayload\n}","typeGuard":"func isValidFragment(size, maxPayload int) bool { return size > 0 && size <= maxPayload }","tryCatchPattern":"payload, err := readRPCFragment(conn)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid fragment size\") {\n        // mark target as non-NFS or hostile; do not retry same connection\n        return ErrNotNFS\n    }\n    return err\n}","preventionTips":["Verify the target port actually speaks NFS/RPC before parsing fragments","Cap maxPayload conservatively and treat oversized headers as hostile input","Validate record-marking last-fragment flag consistency across fragments"],"tags":["network","nfs","rpc","protocol-violation"],"backgroundTag":"value-out-of-range","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"}