golang-gin-gorm-sql注入及解决方案

不要使用动态字符串拼接 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 user
        err := 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)
	//return

	sql := "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)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值