{"record":{"id":"24c87bac08f56660","repo":"projectdiscovery/nuclei","slug":"invalid-host-or-port","errorCode":null,"errorMessage":"invalid host or port","messagePattern":"invalid host or port","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/js/libs/mssql/fingerprint.go","lineNumber":107,"sourceCode":"// const mssql = require('nuclei/mssql');\n// const info = mssql.FingerprintMssql('acme.com', 1433);\n// log(to_json(info));\n// ```\nfunc (c *MSSQLClient) FingerprintMssql(ctx context.Context, host string, port int) (MSSQLInfo, error) {\n\texecutionId := ctx.Value(\"executionId\").(string)\n\treturn memoizedfingerprintMssql(ctx, executionId, host, port)\n}\n\n// @memo\nfunc fingerprintMssql(ctx context.Context, executionId string, host string, port int) (MSSQLInfo, error) {\n\tinfo := MSSQLInfo{\n\t\tHost:      host,\n\t\tPort:      port,\n\t\tProtocol:  \"mssql\",\n\t\tTransport: \"tcp\",\n\t}\n\tif host == \"\" || port <= 0 {\n\t\treturn info, fmt.Errorf(\"invalid host or port\")\n\t}\n\tif !protocolstate.IsHostAllowed(executionId, host) {\n\t\treturn info, protocolstate.ErrHostDenied.Msgf(host)\n\t}\n\tdialer := protocolstate.GetDialersWithId(executionId)\n\tif dialer == nil {\n\t\treturn info, fmt.Errorf(\"dialers not initialized for %s\", executionId)\n\t}\n\n\tconn, err := dialer.Fastdialer.Dial(ctx, \"tcp\", net.JoinHostPort(host, fmt.Sprintf(\"%d\", port)))\n\tif err != nil {\n\t\treturn info, err\n\t}\n\tdefer func() {\n\t\t_ = conn.Close()\n\t}()\n\n\t_ = conn.SetDeadline(time.Now().Add(mssqlFingerprintTimeout))","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mssql/fingerprint.go#L89-L125","documentation":"Returned by mssql.FingerprintMssql when host is an empty string or port is <= 0. It is a pure input-validation failure raised before any network activity; everything else in the function (host allowlist check, dialer lookup, TDS probe) happens after this guard.","triggerScenarios":"mssql.FingerprintMssql('', 1433); mssql.FingerprintMssql('acme.com', 0) — typically because the template derived the port from a variable/extractor that was empty and defaulted to 0, or parsed a host:port string and got an empty host.","commonSituations":"Templates that fingerprint 'on discovery' where the port is optional and frequently missing; passing a URL where the code expected a bare hostname; JS number coercion yielding NaN/0 for a non-numeric port string.","solutions":["Guard the call site: only fingerprint when host is non-empty and port is a positive integer","Apply a sensible default port (1433) when the target is known to be MSSQL","Parse host:port with split(':') and validate both halves before calling"],"exampleFix":"// before\nmssql.FingerprintMssql(target, to_number(port)); // port empty -> 0 -> error\n\n// after\nif (target && to_number(port) > 0) {\n  mssql.FingerprintMssql(target, to_number(port));\n}","handlingStrategy":"validation","validationCode":"const p = to_number(port || 1433);\nif (!host || !(p > 0)) {\n  throw new Error('mssql fingerprint needs a non-empty host and positive port');\n}\nconst info = mssql.FingerprintMssql(String(host), p);","typeGuard":"const validHostPort = (h, p) => typeof h === 'string' && h !== '' && Number.isInteger(p) && p > 0;","tryCatchPattern":null,"preventionTips":["Default the port to 1433 when the service is known to be MSSQL","Validate extractor-derived host/port values before use","Split host:port strings and check both halves are present"],"tags":["mssql","validation","javascript","input-validation","fingerprinting"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}