不要使用动态字符串拼接 dao.db.Raw(sql) 来查询,存在sql注入的风险

!不要动态拼接字符串

解决方案

1. 使用gorm框架语言,自带预编译,能够避免sql注入

2. 使用gorm自带的prepare预加载也能解决,但可能会增加请求往返(有待考量)

eg:(查询操作使用 db.Prepare() 方法声明预处理 SQL,使用 stmt.Query() 将数据替换占位符进行查询,更新、插入、删除操作使用 stmt.Exec() 来操作。)

// 预处理查询数据
func prepareQuery() {sqlStr := "SELECT id,name,age FROM user WHERE id > ?"stmt, err := db.Prepare(sqlStr)if err != nil {fmt.Printf("prepare sql failed, err:%v\n", err)return}rows, err := stmt.Query(1)if err != nil {fmt.Printf("exec failed, err:%v\n", err)return}defer rows.Close()for rows.Next() {var u usererr := rows.Scan(&u.id, &u.name, &u.age)if err != nil {fmt.Printf("scan data failed, err:%v\n", err)return}fmt.Printf("id:%d, name:%s, age:%d\n", u.id, u.name, u.age)}
}

3. 使用Raw的占位符来处理sql注入问题(推荐)

eg:
完美避免测试(使用占位符):

// QueryWaitingApply 7 or 1=1 TODO 占位符解决sql注入
func (as *ArticleService) QueryWaitingApply() (artInfo []mysqlModel.Article) {sql := "select * from articles where boss_id=? and status =?"dao.DB.Raw(sql, "7 or 1=1", 0).Scan(&artInfo)fmt.Println(artInfo)return
}

sql注入成功测试(不使用占位符,纯纯拼接sql)

// QueryWaitingApply 7 or 1=1 TODO 占位符解决sql注入
func (as *ArticleService) QueryWaitingApply() (artInfo []mysqlModel.Article) {//sql := "select * from articles where boss_id=? and status = 0"//dao.DB.Raw(sql, "7 or 1=1").Scan(&artInfo)//fmt.Println(artInfo)//returnsql := "select * from articles where boss_id=7 or 1=1 and status = 0"dao.DB.Raw(sql).Scan(&artInfo)fmt.Println(artInfo)return
}

请注意,gorm不直接支持UNION,您需要使用db.Raw来进行联合:

db.Raw("? UNION ?",db.Select("*").Model(&Foo{}),db.Select("*").Model(&Bar{}),
).Scan(&union)