GoFly框架orm有防SQL注入机制,开发时写sql操作代码也要注意规范

huanglishi · · 396 次点击 · 开始浏览    置顶

# 一、SQL注入问题 大家觉得这样写的​​ sql 会发生sql 注入吗 ?​​ ``` id := "9" + " OR 1=1 " where := "id=" + id data, err := gf.Model("createcode_product").Where(where).Find() ``` 答案是肯定的。那么我们知道,一旦发生字符串的拼接,就会产生这个sql注入的问题。但有同学会疑惑,这个 sql 语句,难道gform不会帮忙预检测的吗? # 二、测试例子 ### 例子1 那么我们可以来实践一下下面两种写法 • 字符串拼接 ``` id := "9" + " AND 1=1 " where := "id=" + id data, err := gf.Model("createcode_product").Where(where).Find() if err != nil { fmt.Println(err) } ``` sql执行日志: ``` SELECT * FROM `createcode_product` WHERE (id=9 OR 1=1) AND `deletetime` IS NULL LIMIT 1 ``` • 直接使用占位符 id := "9" + " OR 1=1 " data, err := gf.Model("createcode_product").Where("id =?",id).Find() if err != nil { fmt.Println(err) } ``` sql执行日志 ```: SELECT * FROM `createcode_product` WHERE (id ='9 OR 1=1 ') AND `deletetime` IS NULL LIMIT 1 ``` 通过打印出执行地SQL语句,我们可以发现这个情况,其实第一种情况的写法这是不行的,因为这里SQL发生了注入,本来只查一条 id为 9的,但是由于后面注入了 1=1 所以把数据库里面的信息全部查出来了。 ​​​第一种的这里是有危险的。​​​,那么我们如何将这个防止呢?其实我们只要按照上面第二种这种做法就好了。因为这样我们才能很好地通过占位符来进行判断。还有其他查询可以参考我们内置功能写,比如: ``` id := "12" + " OR 1=1 " whereMap := gmap.New() whereMap.Set("id", id) data, err := gf.Model("createcode_product").Where(whereMap).Find() ``` 这样写法都可以避免sql注入。 ### 例子2 那么我们再来看看如果注入了两条SQL语句会怎么样? 比如说这个 ``` id := "9; drop table notice;" //删除notice数据表 where := "id=" + id data, err := gf.Model("createcode_product").Where(where).Find() if err != nil { gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c) } else { gf.Success().SetMsg("get请求测试").SetData(data).Regin(c) } ``` 执行日志: ``` Error: Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; drop table notice;) AND `deletetime` IS NULL LIMIT 1' at line 1 ``` 如果你直接执行sql语句(直接注入了drop table notice ),那么最终的SQL语句如下: SELECT * FROM `createcode_product` WHERE id=9; drop table notice;所以这个在SQL里面肯定是可以执行的。但是在gform这个框架中是不能执行的。这样包含我们数据安全。 三、总结 所以说我们要避免使用字符串直接拼接的形式来进行SQL的查询,开发是要是使用我们框架提倡写法,如使用站位符? gmap.New(),whereMap.Set("id", id) whereMap.Set("id=?", id)等,不要直接写原生sql语句。 四、完整代码 ``` package createcode import ( "gofly/utils/gf" ) // 后端代码 type Testsql struct{} func init() { fpath := Testsql{} gf.Register(&fpath, fpath) } // get请求 func (api *Testsql) GetList(c *gf.GinCtx) { //例子 1 // id := "12" + " OR 1=1 " // whereMap := gmap.New() // whereMap.Set("id", id) // // where := "id=" + id // data, err := gf.Model("createcode_product").Where(whereMap).Find() // if err != nil { // gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c) // } else { // gf.Success().SetMsg("get请求测试").SetData(data).Regin(c) // } //例子2 id := "9; drop table notice;" //登上删除notice数据表 where := "id=" + id data, err := gf.Model("createcode_product").Where(where).Find() if err != nil { gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c) } else { gf.Success().SetMsg("get请求测试").SetData(data).Regin(c) } } ```

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

396 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传