Golang

时间:2015-07-27 07:37:57

标签: security go escaping

我想要转义构成数据库查询一部分的值,但我不能使用参数化查询。

Go是否具有相同的PHP mysql_real_escape_string我可以用来转义查询值?

4 个答案:

答案 0 :(得分:6)

我想出了自己的解决方案来自己创建这个功能 希望它对某人有用。

func MysqlRealEscapeString(value string) string {
    replace := map[string]string{"\\":"\\\\", "'":`\'`, "\\0":"\\\\0", "\n":"\\n", "\r":"\\r", `"`:`\"`, "\x1a":"\\Z"}

    for b, a := range replace {
        value = strings.Replace(value, b, a, -1)
    }

    return value
}

答案 1 :(得分:4)

如果整个查询 - 或超出单个值的查询的任何部分 - 从命令行传递,则无法逃脱。

mysql_real_escape_string及其表兄弟用于清理单个值,以防止任何有权访问该值的人在插入查询之前“突破”并摆弄查询本身。

鉴于您正在向外部提供对整个查询的访问权限,因此逃避功能无法提高安全性。

你唯一的安检是

  • 在不会造成任何损害的用户上下文中执行查询(例如,您可以在mySQL中基于每个用户限制命令)
  • 确保正确捕获并处理查询错误
  • 正如Not_a_Golfer在上面的评论中建议的,解析查询中的任何恶意内容

答案 2 :(得分:0)

为此,您可以使用准备好的查询。

检索多行

stmt, err := db.Prepare("select id, name from users where id = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
    // ...
}
if err = rows.Err(); err != nil {
    log.Fatal(err)
}

检索单行

var name string
err = db.QueryRow("select name from users where id = ?", 1).Scan(&name)
if err != nil {
    log.Fatal(err)
}
fmt.Println(name)

答案 3 :(得分:0)

改进的答案:

func MysqlRealEscapeString(value string) string {
    var sb strings.Builder
    for i := 0; i < len(value); i++ {
        c := value[i]
        switch c {
        case '\\', 0, '\n', '\r', '\'', '"':
            sb.WriteByte('\\')
            sb.WriteByte(c)
        case '\032':
            sb.WriteByte('\\')
            sb.WriteByte('Z')
        default:
            sb.WriteByte(c)
        }
    }
    return sb.String()
}