{"record":{"id":"517aa2a2abbd3057","repo":"shadow1ng/fscan","slug":"mssql-prelogin-response-missing-encryption-field","errorCode":null,"errorMessage":"mssql: prelogin response missing encryption field","messagePattern":"mssql: prelogin response missing encryption field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":165,"sourceCode":"\nfunc mssqlReadPrelogin(r io.Reader) error {\n\tpacketType, payload, err := mssqlReadMessage(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif packetType != tdsPacketReply {\n\t\treturn fmt.Errorf(\"mssql: invalid prelogin response packet type %d\", packetType)\n\t}\n\tif len(payload) == 0 {\n\t\treturn fmt.Errorf(\"mssql: empty prelogin response\")\n\t}\n\n\tfields, err := mssqlParsePreloginFields(payload)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, ok := fields[tdsPreloginEncryption]; !ok {\n\t\treturn fmt.Errorf(\"mssql: prelogin response missing encryption field\")\n\t}\n\treturn nil\n}\n\nfunc mssqlParsePreloginFields(payload []byte) (map[byte][]byte, error) {\n\tfields := make(map[byte][]byte)\n\tfor pos := 0; ; pos += 5 {\n\t\tif pos >= len(payload) {\n\t\t\treturn nil, fmt.Errorf(\"mssql: invalid prelogin option table\")\n\t\t}\n\t\ttoken := payload[pos]\n\t\tif token == tdsPreloginTerminator {\n\t\t\treturn fields, nil\n\t\t}\n\t\tif pos+5 > len(payload) {\n\t\t\treturn nil, fmt.Errorf(\"mssql: truncated prelogin option\")\n\t\t}\n\t\toffset := int(binary.BigEndian.Uint16(payload[pos+1 : pos+3]))","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L147-L183","documentation":"The prelogin response parsed successfully but did not include the ENCRYPT option (token 0x01), which the TDS spec requires in every prelogin response. Without it the library cannot determine the server's encryption preference for the subsequent Login7.","triggerScenarios":"mssqlParsePreloginFields returns a map lacking key tdsPreloginEncryption (1) — the server omitted the encryption option from its option table.","commonSituations":"Non-Microsoft TDS implementations (e.g. FreeTDS-based gateways) with incomplete prelogin; corrupted or hand-crafted responses; very old or patched server builds.","solutions":["Confirm the server is genuine Microsoft SQL Server; test with sqlcmd or go-mssqldb.","If connecting through a TDS proxy/gateway, check it forwards the full prelogin response option table.","If the endpoint is under your control, patch/upgrade the TDS implementation to include option 0x01.","Capture the response packet and verify which prelogin options were actually returned."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the peer is real SQL Server before probing:\nout, err := exec.Command(\"sqlcmd\", \"-S\", host+\",\"+fmt.Sprint(port), \"-Q\", \"SELECT 1\", \"-l\", \"5\").CombinedOutput()\nif err != nil { /* not a healthy SQL Server */ }","typeGuard":null,"tryCatchPattern":"_, err := mssqlRawLogin(ctx, host, port, user, pass, timeout)\nif err != nil && strings.Contains(err.Error(), \"missing encryption field\") {\n    // server/proxy sent incomplete prelogin; treat endpoint as non-standard TDS\n}","preventionTips":["Prefer full drivers for non-vanilla endpoints (FreeTDS gateways, proxies).","Verify the server build supports the TDS 7.x prelogin option table fully.","Log raw prelogin responses when connecting to unusual endpoints."],"tags":["mssql","tds","prelogin","encryption","protocol"],"backgroundTag":"unexpected-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"}