{"id":"e4bf52c1a1a60255","repo":"go-sql-driver/mysql","slug":"invalid-dsn-interpolateparams-can-not-be-used-wit","errorCode":null,"errorMessage":"invalid DSN: interpolateParams can not be used with unsafe collations","messagePattern":"invalid DSN: interpolateParams can not be used with unsafe collations","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dsn.go","lineNumber":32,"sourceCode":"\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar (\n\terrInvalidDSNUnescaped       = errors.New(\"invalid DSN: did you forget to escape a param value?\")\n\terrInvalidDSNAddr            = errors.New(\"invalid DSN: network address not terminated (missing closing brace)\")\n\terrInvalidDSNNoSlash         = errors.New(\"invalid DSN: missing the slash separating the database name\")\n\terrInvalidDSNUnsafeCollation = errors.New(\"invalid DSN: interpolateParams can not be used with unsafe collations\")\n)\n\n// Config is a configuration parsed from a DSN string.\n// If a new Config is created instead of being parsed from a DSN string,\n// the NewConfig function should be used, which sets default values.\ntype Config struct {\n\t// non boolean fields\n\n\tUser                 string            // Username\n\tPasswd               string            // Password (requires User)\n\tNet                  string            // Network (e.g. \"tcp\", \"tcp6\", \"unix\". default: \"tcp\")\n\tAddr                 string            // Address (default: \"127.0.0.1:3306\" for \"tcp\" and \"/tmp/mysql.sock\" for \"unix\")\n\tDBName               string            // Database name\n\tParams               map[string]string // Connection parameters\n\tConnectionAttributes string            // Connection Attributes, comma-delimited string of user-defined \"key:value\" pairs\n\tCollation            string            // Connection collation. When set, this will be set in SET NAMES <charset> COLLATE <collation> query\n\tLoc                  *time.Location    // Location for time.Time values\n\tMaxAllowedPacket     int               // Max packet size allowed","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/dsn.go#L14-L50","documentation":"normalize() refuses the combination interpolateParams=true with a collation on the unsafeCollations denylist (collations.go:253: big5, sjis, gbk, cp932, gb18030 variants). These multibyte collations can carry a 0x5c ('\\') in a trailing byte, which makes client-interpolated parameter values injectable, so the driver aborts at dsn.go:174 before opening.","triggerScenarios":"A DSN like 'user@tcp(host)/db?interpolateParams=true&collation=gbk_chinese_ci', or a Config with InterpolateParams=true and Collation='big5_bin', passed to sql.Open/NewConnector.","commonSituations":"Enabling interpolateParams for performance on a legacy Asian-language MySQL (gbk/big5/sjis); porting a DSN from a utf8 (safe) project to one using a multibyte Asian collation; CI passes with utf8mb4 but production uses sjis.","solutions":["Keep interpolateParams and switch the collation to a safe one (e.g. utf8mb4_general_ci or utf8mb4_0900_ai_ci).","Keep the unsafe collation and disable interpolateParams; the driver will use server-side prepared statements instead.","Leave cfg.Collation empty and rely on a safe server-default collation."],"exampleFix":"// before\ndsn := \"user@tcp(host:3306)/db?interpolateParams=true&collation=gbk_chinese_ci\"\n// after\ndsn := \"user@tcp(host:3306)/db?interpolateParams=true&collation=utf8mb4_0900_ai_ci\"","handlingStrategy":"validation","validationCode":"var unsafeCollations = map[string]bool{\n    \"big5_chinese_ci\": true, \"sjis_japanese_ci\": true, \"gbk_chinese_ci\": true,\n    \"big5_bin\": true, \"gb2312_bin\": true, \"gbk_bin\": true, \"sjis_bin\": true,\n    \"cp932_japanese_ci\": true, \"cp932_bin\": true,\n    \"gb18030_chinese_ci\": true, \"gb18030_bin\": true, \"gb18030_unicode_520_ci\": true,\n}\nfunc safeCombo(interpolate bool, collation string) bool {\n    return !(interpolate && collation != \"\" && unsafeCollations[collation])\n}","typeGuard":null,"tryCatchPattern":"if _, err := mysql.ParseDSN(dsn); err != nil && strings.Contains(err.Error(), \"unsafe collations\") {\n    // drop interpolateParams or switch collation to utf8mb4_0900_ai_ci\n}","preventionTips":["Do not combine interpolateParams with Asian multibyte collations (big5/sjis/gbk/cp932/gb18030).","Default to utf8mb4 collations unless the schema specifically requires otherwise.","Add a CI check that flags interpolateParams in DSNs that also set collation."],"tags":["go","mysql","dsn","security","sql-injection","collation"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}