ORM 盛行下,你知道真正执行的 sql 么

VSole2022-08-03 16:11:35

推荐理由

在这个 orm 盛行的服务端开发环境下,已经很少有人写 raw sql 了吧,毕竟 orm 框架可以帮助开发人员屏蔽 db 的细节,同时还能在一定成程度上预防 sql 注入的风险,大多数情况下,对业务代码的单测,会使用 sqlite 来 mock 真正的 db,以验证功能的完备性,但当你写完一条 orm 语句后,是否会校验,生成的真正执行的 sql 是你的预期么?是否会校验,在代码变更的时候 sql 语句是否也发生了变更呢?

针对以上两个问题,sqlmock 可以完成对 sql 语句的单侧,让你对 orm 生成的 sql 了如指掌,同时清晰 test raw sql 也让 review 的同事快乐加倍。

实现原理

其实 sql mock 只是实现了 go sql/driver 的接口,用于模拟数据库的连接,本质上并不会进行存储数据,只能特定的返回。

实际栗子

通过 sqlmock 测试创建 user 的sql语句
package main
import (
  "github.com/DATA-DOG/go-sqlmock"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
  "testing"
)
type User struct {
  ID int64 `gorm:"column:id"`
  UserName string `gorm:"column:user_name"`
}
func (User) TableName() string {
  return "users"
}
func CreateUser(db *gorm.DB, user *User) error{
  return db.Table(user.TableName()).Create(&user).Error
}
const (
  rawSQLCreateUser = "INSERT INTO `users` (`user_name`,`id`) VALUES (?,?)"
)
func TestShouldUpdateStats(t *testing.T) {
  db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
  if err != nil {
    t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
  }
  defer db.Close()
  dialector := mysql.New(mysql.Config{
    DriverName:                "mysql",
    Conn:                      db,
    SkipInitializeWithVersion:true,
  })
  user := &User{
    ID:       1,
    UserName: "zr",
  }
  gdb, err := gorm.Open(dialector, &gorm.Config{})
  gdb = gdb.Debug()
  mock.ExpectBegin()
  mock.ExpectExec(rawSQLCreateUser).
    WithArgs(user.UserName,user.ID).WillReturnResult(sqlmock.NewResult(1, 1))
  mock.ExpectCommit()
  if err = CreateUser(gdb, user); err != nil {
    t.Errorf("gorm create fail, err=%v", err)
  }
  if err = mock.ExpectationsWereMet(); err != nil {
    t.Errorf("unexcept sql, err=%v", err)
  }
}

总结

PS:笔者的老板对 sql 治理比较看重,所以在业务实现中会在存储层对于每一个 sql 写 sqlmock。

sqlmock 虽然不能对整个业务功能进行集成测试,但是在 dao 层,对存储数据的操作进行 sql 语句层面的校验个人觉得是有必要的,一方面这会使 sql 的管理更加高效(将定义的 rawsql 单独放在一个文件中),另一方面,数据库层面改动时,有完整的 sql 校验逻辑,方便 review 的人直观的看出来具体数据有什么变化。

顺带一提:这个库的开源作者想要找个开源维护者,感兴趣的也可以参与尝试下。

sql注入orm
本作品采用《CC 协议》,转载必须注明作者和本文链接
前言SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少。Mybatis中SQL语句需要我们自己手动编写或者用generator自动生成。编写xml文件时,MyBatis支持两种参数符号,一种是#,另一种是$。
防范SQL注入的三个大招
是否会校验,在代码变更的时候 sql 语句是否也发生了变更呢?针对以上两个问题,sqlmock 可以完成对 sql 语句的单侧,让你对 orm 生成的 sql 了如指掌,同时清晰 test raw sql 也让 review 的同事快乐加倍。
在所有漏洞类型中,SQL 注入可是说是危害最大最受大家关注的漏洞。简单说来,SQL 注入是通过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料之外结果的攻击行为。还是以 ThinkJS 为例,假设我们写了如下一个接口(实际情况肯定不会这么写的):
Django 数据库函数 Trunc 和 Extract 主要用于进行日期操作,如果将未过滤的数据传递给 kind 或 lookup_name 时,将会产生 SQL 注入漏洞 CVE-2022-34265。
sql注入已经出世很多年了,对于sql注入的概念和原理很多人应该是相当清楚了,SSTI也是注入类的漏洞,其成因其实是可以类比于sql注入的。BladeBlade 是 Laravel 提供的一个既简单又强大的模板引擎。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
业务逻辑漏洞挖掘
2022-06-08 08:48:17
一. 前言随着各类前后端框架的成熟和完善,传统的SQL注入、XSS等常规漏洞在Web系统里逐步减少,而攻击者
ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP5.0以上版本支持,支持MySql、PgSQL、Sqlite多种数据库以及PDO扩展,是一款跨平台,跨版本以及简单易用的PHP框架。导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞。preg_replace这个函数使用方法如下:preg_replace. 关于/e的解释:e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;/e 可执行模式,此为PHP专有参数,例如preg_replace函数。
ThinkPHP框架漏洞总结
2023-05-18 15:25:22
ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP5.0以上版本支持,支持MySql、PgSQL、Sqlite多种数据库以及PDO扩展,是一款跨平台,跨版本以及简单易用的PHP框架。导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞。preg_replace这个函数使用方法如下:preg_replace. 关于/e的解释:e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行;> #需要进行url编码
Thinkphp是一个国内轻量级的开发框架,采用php+apache,在更新迭代中,thinkphp也经常爆出各种漏洞,thinkphp一般有thinkphp2、thinkphp3、thinkphp5、thinkphp6版本,前两个版本已经停止更新
VSole
网络安全专家