G

[Golang] GORM框架 Exec和Raw

RoLingG 2024-10-10

Exec和Raw

Exec

Exec 方法用于执行原生 SQL 语句,并且可以返回 SQL 执行的结果。这个方法通常用于执行更新、删除或执行存储过程等操作。

result := DB.Exec("UPDATE users SET age = ? WHERE name = ?", 22, "John")
rowCount, err := result.RowsAffected() // 获取受影响的行数
if err != nil {
    // 处理错误
}
fmt.Println("Affected rows:", rowCount)

Raw

Raw 方法用于构建并执行原生 SQL 查询,它返回一个 *sql.Rows 结果集,你可以遍历这个结果集来获取查询的数据。

rows, err := DB.Raw("SELECT name, age FROM users WHERE age > ?", 18).Rows()
if err != nil {
    // 处理错误
}
defer rows.Close() // 确保关闭结果集

var name string
var age int
// 遍历 rows 来获取每一行的数据
for rows.Next() {
    err := rows.Scan(&name, &age)
    if err != nil {
        // 处理错误
    }
    fmt.Println("Name:", name, "Age:", age)
}

但是注意了,这两个语句都有被进行SQL注入攻击的风险,例如:

username := "user_input" // 假设这是从请求中获取的用户输入
password := "pass_input" // 假设这是从请求中获取的用户输入

// 错误示范:直接拼接用户输入
sql := "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"
// 执行SQL查询...

//如果用户输入如下:
username: 'admin'; DROP TABLE users; --
password: 'password'

// 拼接完的语句就变成了
SELECT * FROM users WHERE username = 'admin'; DROP TABLE users; --' AND password = 'password'

为什么会可能被SQL注入攻击:

  1. 直接拼接用户输入:如果用户输入直接拼接到SQL语句中,攻击者可以输入恶意SQL代码,导致应用程序执行非预期的SQL命令。
  2. 缺乏输入验证:应用程序没有正确验证用户输入,或者验证机制不够强大,使得攻击者可以绕过输入限制。
  3. 使用动态SQL:动态构建SQL语句时,如果没有使用参数化查询或适当的转义机制,就可能导致SQL注入漏洞。
  • 这些方法执行的是原生 SQL,所以它们不会受到 GORM 的钩子(callbacks)和中间件的影响。
  • 当你使用 Raw 方法时,确保在最后调用 rows.Close() 来关闭结果集,避免内存泄漏。

因此最好少一些使用 ExecRaw 去进行操作数据库数据,而是采用参数化查询来防止 SQL 注入攻击,GORM 会将用户输入作为参数绑定到 SQL 语句中,而不是直接拼接到 SQL 字符串中。这种方法确保了用户输入不会被解释为 SQL 代码的一部分。

参数化查询的工作原理
参数化查询使用占位符(如问号 ?)来表示查询中的变量部分,然后将这些占位符的安全值在查询执行时传递给数据库。数据库驱动接管这些值,并确保它们正确地转义,以防止它们被作为 SQL 代码执行。

结构体化

GORM结构体化也可以有效的避免SQL注入,应尽量避免直接用SQL语句来执行增删改查。
例如:err = db.Where(clause.Gte{Column: clause.Column{Name: "id"}, Value: 1}).First(&u1).Error 这里用了 clause.Gte 结构体,里面通过 clause.Column 来加入我们要查询的字段,Value则为值,Gte的意思是大于等于,同理还有Eq(等于)、Gt(大于)、Lt(小于)、Lte(小于等于)等结构体,用于查询。

这样做既预防了SQL注入的风险,也通过结构体化将id这个字段加上了双引号作为SQL语句的查询限制条件,有效的避免了一些数据库id字段为特殊字段不给使用的情况。

PREV
[Golang] GORM框架 核心
NEXT
[Golang] GORM框架 三种特殊查询

评论(0)

发布评论