{"record":{"id":"d43bd871aa3e4233","repo":"projectdiscovery/nuclei","slug":"invalid-host-or-port-d43bd8","errorCode":null,"errorMessage":"invalid host or port","messagePattern":"invalid host or port","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/js/libs/mysql/mysql_private.go","lineNumber":49,"sourceCode":"\t\tPassword string // Password is the password used to authenticate with the MySQL server.\n\t\tDbName   string // DbName is the name of the database to connect to on the MySQL server.\n\t\tRawQuery string // QueryStr is the query string to append to the DSN (ex: \"?tls=skip-verify\").\n\t\tTimeout  int    // Timeout is the timeout in seconds for the connection to the MySQL server.\n\t}\n)\n\n// BuildDSN builds a MySQL data source name (DSN) from the given options.\n// @example\n// ```javascript\n// const mysql = require('nuclei/mysql');\n// const options = new mysql.MySQLOptions();\n// options.Host = 'acme.com';\n// options.Port = 3306;\n// const dsn = mysql.BuildDSN(options);\n// ```\nfunc BuildDSN(opts MySQLOptions) (string, error) {\n\tif opts.Host == \"\" || opts.Port <= 0 {\n\t\treturn \"\", fmt.Errorf(\"invalid host or port\")\n\t}\n\tif opts.Protocol == \"\" {\n\t\topts.Protocol = \"tcp\"\n\t}\n\t// We're going to use a custom dialer when creating MySQL connections, so if we've been\n\t// given \"tcp\" as the protocol, then quietly switch it to \"nucleitcp\", which we have\n\t// already registered.\n\tif opts.Protocol == \"tcp\" {\n\t\topts.Protocol = \"nucleitcp\"\n\t}\n\tif opts.DbName == \"\" {\n\t\topts.DbName = \"/\"\n\t} else {\n\t\topts.DbName = \"/\" + opts.DbName\n\t}\n\ttarget := net.JoinHostPort(opts.Host, fmt.Sprintf(\"%d\", opts.Port))\n\tvar dsn strings.Builder\n\tfmt.Fprintf(&dsn, \"%v:%v\", url.QueryEscape(opts.Username), opts.Password)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mysql/mysql_private.go#L31-L67","documentation":"Returned by BuildDSN when MySQLOptions.Host is empty or MySQLOptions.Port is <= 0 — the two mandatory fields for a TCP DSN. BuildDSN is called internally by Connect/ExecuteQuery (which supply host/port) but is also exported for direct use from JS, where forgetting to populate the options struct is easy. All later defaults (protocol tcp→nucleitcp, DbName) are applied only after this check passes.","triggerScenarios":"Constructing mysql.MySQLOptions in JS and calling mysql.BuildDSN(opts) without setting opts.Host or with opts.Port left at the zero value / set to 0 or a negative number. Also a port parsed from untrusted input that yields 0 or NaN.","commonSituations":"JS templates that build options dynamically from extractor output (empty host match); copy-paste from the doc example that only sets Username/Password; passing a port as string into the int field; iterating targets where some entries have no port.","solutions":["Set Host and a valid Port (1-65535) on MySQLOptions before calling BuildDSN","Validate inputs derived from extractors/variables before building the DSN","Prefer the convenience APIs Connect/ExecuteQuery which take host/port arguments directly and are harder to get wrong","Add a guard clause in the template: if (!opts.Host || !(opts.Port > 0)) skip"],"exampleFix":"// before\nconst opts = new mysql.MySQLOptions();\nopts.Username = 'root';\nconst dsn = mysql.BuildDSN(opts); // invalid host or port\n\n// after\nconst opts = new mysql.MySQLOptions();\nopts.Host = 'acme.com';\nopts.Port = 3306;\nopts.Username = 'root';\nconst dsn = mysql.BuildDSN(opts);","handlingStrategy":"validation","validationCode":"if (!opts.Host || !(opts.Port > 0) || opts.Port > 65535) {\n  throw new Error('host and port required before BuildDSN');\n}\nconst dsn = mysql.BuildDSN(opts);","typeGuard":"function isValidTarget(host, port) {\n  return typeof host === 'string' && host.length > 0 && Number.isInteger(port) && port > 0 && port <= 65535;\n}","tryCatchPattern":"try { mysql.BuildDSN(opts); } catch (e) { if (String(e) === 'invalid host or port') { /* fix opts and rebuild */ } else { throw e; } }","preventionTips":["Always set Host and Port on MySQLOptions — they have no defaults","Sanitize extractor-derived host/port before building DSNs","Validate ports as integers 1-65536; reject NaN/0","Prefer Connect/ExecuteQuery signatures that take host/port directly"],"tags":["mysql","input-validation","dsn"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}