{"record":{"id":"1826192e0d4308f7","repo":"shadow1ng/fscan","slug":"mssql-invalid-token-size","errorCode":null,"errorMessage":"mssql: invalid token size","messagePattern":"mssql: invalid token size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":391,"sourceCode":"\t\tif pos+length > end {\n\t\t\treturn fmt.Errorf(\"mssql: invalid string in error token\")\n\t\t}\n\t\tpos += length\n\t}\n\tif pos+4 > end {\n\t\treturn fmt.Errorf(\"mssql: truncated error line number\")\n\t}\n\treturn nil\n}\n\nfunc mssqlSkipLen16(payload []byte, pos int) (int, error) {\n\tif pos+2 > len(payload) {\n\t\treturn pos, fmt.Errorf(\"mssql: truncated token\")\n\t}\n\tsize := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))\n\tnext := pos + 2 + size\n\tif next > len(payload) {\n\t\treturn pos, fmt.Errorf(\"mssql: invalid token size\")\n\t}\n\treturn next, nil\n}\n\nfunc mssqlReadUSVarChar(payload []byte, pos int) (string, int, error) {\n\tif pos+2 > len(payload) {\n\t\treturn \"\", pos, fmt.Errorf(\"mssql: truncated us varchar\")\n\t}\n\tchars := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))\n\tpos += 2\n\tsize := chars * 2\n\tif pos+size > len(payload) {\n\t\treturn \"\", pos, fmt.Errorf(\"mssql: invalid us varchar size\")\n\t}\n\treturn mssqlDecodeUCS2(payload[pos : pos+size]), pos + size, nil\n}\n\nfunc mssqlWritePacket(w io.Writer, packetType byte, payload []byte) error {","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L373-L409","documentation":"mssqlSkipLen16 read a token's 2-byte length and computed the next token position, but pos+2+size exceeds the payload length — the token body claims more bytes than the response actually contains. The library throws 'invalid token size' rather than skipping into nonexistent bytes.","triggerScenarios":"A length-prefixed token in the login response declares a size that overruns the end of the payload (pos+2+size > len(payload)).","commonSituations":"Truncated TCP stream with a corrupted trailing length; fuzzer or hostile server inflating the length field to trigger over-reads; middlebox splicing segments incorrectly.","solutions":["Retry the login and check whether the error reproduces deterministically.","Packet-capture the response and validate the token's declared size against the actual byte count.","Check MTU/fragmentation issues or proxies that may drop trailing bytes.","Treat the response as corrupt: abort the connection instead of continuing to parse."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"size := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))\nif pos+2+size > len(payload) {\n    return fmt.Errorf(\"token size %d overruns payload end %d\", size, len(payload))\n}","typeGuard":null,"tryCatchPattern":"next, err := mssqlSkipLen16(payload, pos)\nif err != nil {\n    conn.Close()\n    return fmt.Errorf(\"server response framing violated: %w\", err)\n}","preventionTips":["Validate every declared length against remaining payload bytes.","Check MTU/fragmentation handling in your TCP read loop.","Isolate whether a middlebox is splicing TCP segments incorrectly.","Abort parsing after any overrun; token stream integrity is broken."],"tags":["mssql","tds-protocol","malformed-packet","wire-parsing"],"backgroundTag":"unexpected-api-response-shape","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"}