{"record":{"id":"2af08f97eb9f407c","repo":"vitessio/vitess","slug":"invalid-session-variable-name-q","errorCode":null,"errorMessage":"invalid session variable name: %q","messagePattern":"invalid session variable name: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"go/vt/schema/ddl_strategy.go","lineNumber":213,"sourceCode":"func (setting *DDLStrategySetting) IsSingletonContext() bool {\n\treturn setting.hasFlag(singletonContextFlag)\n}\n\n// IsSingletonTable checks if strategy options include --singleton-table\nfunc (setting *DDLStrategySetting) IsSingletonTable() bool {\n\treturn setting.hasFlag(singletonTableFlag)\n}\n\n// IsAllowZeroInDateFlag checks if strategy options include --allow-zero-in-date\nfunc (setting *DDLStrategySetting) IsAllowZeroInDateFlag() bool {\n\treturn setting.hasFlag(allowZeroInDateFlag)\n}\n\n// ValidateSessionVariable ensures a variable name is safe to interpolate as a\n// MySQL system variable identifier.\nfunc ValidateSessionVariable(variable SessionVariable) error {\n\tif !sessionVariableNameRegexp.MatchString(variable.Name) {\n\t\treturn fmt.Errorf(\"invalid session variable name: %q\", variable.Name)\n\t}\n\tif _, ok := deniedSessionVariables[strings.ToLower(variable.Name)]; ok {\n\t\treturn fmt.Errorf(\"session variable %q is not allowed\", variable.Name)\n\t}\n\treturn nil\n}\n\n// ValidateSessionVariables validates variable names and rejects\n// case-insensitive duplicates.\nfunc ValidateSessionVariables(variables []SessionVariable) error {\n\tseen := map[string]struct{}{}\n\tfor _, variable := range variables {\n\t\tif err := ValidateSessionVariable(variable); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tnormalizedName := strings.ToLower(variable.Name)\n\t\tif _, ok := seen[normalizedName]; ok {\n\t\t\treturn fmt.Errorf(\"duplicate session variable name: %q\", variable.Name)","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/schema/ddl_strategy.go#L195-L231","documentation":"ValidateSessionVariable checks that a session variable name parsed from a ddl_strategy-style value is a safe MySQL system-variable identifier before it is interpolated into SQL. If the name does not match sessionVariableNameRegexp, it is rejected to prevent injection of arbitrary SQL through variable names.","triggerScenarios":"Calling schema.ValidateSessionVariable (or SetStatement / ValidateSessionVariables) with a SessionVariable whose Name contains illegal characters — spaces, quotes, semicolons, parentheses, or other non-identifier characters.","commonSituations":"Malformed SET @@ddl_strategy input like 'sql_mode=...; DROP TABLE x' or a name with stray whitespace; app code building session variables from untrusted user input; parsing bugs splitting name=value pairs incorrectly.","solutions":["Pass only valid MySQL identifier-style variable names (letters, digits, underscore) in the SessionVariable.","Sanitize/trim user-supplied variable strings before constructing SessionVariable values.","Check the denied-session-variables list too — even well-formed names like some privileged variables are rejected by the companion check.","Fix the parser/splitter that produced a name containing '=' or whitespace."],"exampleFix":"// before\nv := SessionVariable{Name: \"sql_mode; DROP TABLE t\", Value: \"x\"}\nValidateSessionVariable(v) // error\n// after\nv := SessionVariable{Name: \"sql_mode\", Value: \"STRICT_TRANS_TABLES\"}\nValidateSessionVariable(v) // nil","handlingStrategy":"validation","validationCode":"var nameRe = regexp.MustCompile(`^[A-Za-z0-9_]+$`)\nif !nameRe.MatchString(v.Name) { return fmt.Errorf(\"unsafe variable name %q\", v.Name) }","typeGuard":"func isSafeVarName(name string) bool {\n  for _, r := range name {\n    if !(r == '_' || (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9')) { return false }\n  }\n  return len(name) > 0\n}","tryCatchPattern":"if err := schema.ValidateSessionVariable(v); err != nil {\n  return fmt.Errorf(\"session variable rejected: %w\", err)\n}","preventionTips":["Never build variable names from raw user input","Trim whitespace before constructing SessionVariable","Sanitize the name=value split of ddl_strategy parameters"],"tags":["ddl","validation","sql-injection"],"backgroundTag":"invalid-session-variable-name","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}