SQL
参数化sql
手动拼接sql就会有sql注入的风险, 即使是处理了转义, 仍有可能存在漏洞, 为了解决这个问题, 通常可以使用占位符代替实际参数
值得一提的是, gorm和jdbc的参数都是在服务端处理的, psycopg2的参数是在客户端处理的, 所以仍有可能存在注入的风险
gorm
| |
JDBC
| |
psycopg2
| |
预编译
预编译的原理: 向服务器发送一段sql, 并且携带一个id, 后续就可以通过id来复用这段sql, 减少IO和sql解析的开销(其实就和声明函数有点类似,后续只需要发送函数名和参数即可调用)。
对于java而言, 下面这段代码就非常常见, 甚至是每个java初学者都写过的。
| |
查阅网络资料以及各种视频, 都说这段代码可以预编译,事实上是不对的, 这段代码实现预编译有一些条件
- 必须重复调用5次以上, 才能预编译
- 参数数量必须是固定的
对于1, 我们可以理解成前五次还是正常调用的,第六次开始才是预编译
对于2, 比如说 select * from users where id = ? 这样就是一个固定参数,就可以预编译, 如果是 select * from users where id in ?
在in里面可能是一个数组, 这样就不属于一个参数,无法预编译
报文
下面这段信息由抓包得来,当我们发起一个sql预编译请求,报文如下
| |
随后向服务端发送调用请求
| |
需要说明一下, [len]表示后续的字符数量,为固定四个字节, 也就是说sql的最大长度大约是 (1<<31)