浏览代码

Use blacklist to avoid vulnerability with interpolation

INADA Naoki 11 年之前
父节点
当前提交
90cb6c31d5
共有 2 个文件被更改,包括 16 次插入24 次删除
  1. 14 0
      collations.go
  2. 2 24
      utils.go

+ 14 - 0
collations.go

@@ -234,3 +234,17 @@ var collations = map[string]byte{
 	"utf8mb4_unicode_520_ci":   246,
 	"utf8mb4_vietnamese_ci":    247,
 }
+
+// A blacklist of collations which is unsafe to interpolate parameters.
+// These multibyte encodings may contains 0x5c (`\`) in their trailing bytes.
+var unsafeCollations = map[byte]bool{
+	1:  true, // big5_chinese_ci
+	13: true, // sjis_japanese_ci
+	28: true, // gbk_chinese_ci
+	84: true, // big5_bin
+	86: true, // gb2312_bin
+	87: true, // gbk_bin
+	88: true, // sjis_bin
+	95: true, // cp932_japanese_ci
+	96: true, // cp932_bin
+}

+ 2 - 24
utils.go

@@ -148,30 +148,8 @@ func parseDSN(dsn string) (cfg *config, err error) {
 		return nil, errInvalidDSNNoSlash
 	}
 
-	if cfg.interpolateParams && cfg.collation != defaultCollation {
-		// A whitelist of collations which safe to interpolate parameters.
-		// ASCII and latin-1 are safe since they are single byte encoding.
-		// utf-8 is safe since it doesn't conatins ASCII characters in trailing bytes.
-		safeCollations := []string{"ascii_", "latin1_", "utf8_", "utf8mb4_"}
-
-		var collationName string
-		for name, collation := range collations {
-			if collation == cfg.collation {
-				collationName = name
-				break
-			}
-		}
-
-		safe := false
-		for _, p := range safeCollations {
-			if strings.HasPrefix(collationName, p) {
-				safe = true
-				break
-			}
-		}
-		if !safe {
-			return nil, errInvalidDSNUnsafeCollation
-		}
+	if cfg.interpolateParams && unsafeCollations[cfg.collation] {
+		return nil, errInvalidDSNUnsafeCollation
 	}
 
 	// Set default network if empty