侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

预处理之SQL参数化查询是如何防止SQL注入的浅析

数据库  /  管理员 发布于 1星期前   43

SQL注入是什么?

将 SQL 命令插入到表单提交或输入域名或页面请求的查询字符串中,欺骗服务器执行恶意的 SQL 命令。

 -- 正常的查询语句
 select * from users where username = 'a';
 -- 恶意的查询语句
 select * from users where username = 'a' or 1==1;

参数化查询是什么?

参数化查询是指查询数据库时,在需要填入数据的地方,使用参数来给值。

set @id = 1;
SELECT * from users WHERE id = @id ;


SQL语句的执行处理

SQL语句按处理流程看有两类:即时 SQL、预处理 SQL。


即时 SQL

即时 SQL 从 DB 接收到最终执行完毕返回,大致的过程如下:

  a. 词法和语义解析
  b. 优化sql语句,制定执行计划
  c. 执行并返回结果

特点:

一次编译,单次运行。



预处理SQL

程序中某条 sql 可能会被反复调用,或者每次执行的时候只有个别的值不同。

如果每次按即时 SQL 的流程来看,效率是比较低的。

这时候可以将 SQL 中的值用占位符代替,先生成 SQL 模板,然后再绑定参数,之后重复执行该语句的时候只需要替换参数,而不用再去进行词法和语义分析。

可以视为 SQL 语句模板化或参数化。

特点:

一次编译,多次运行,省去了多次解析等过程。

(多次运行是指在同一会话中再次执行相同的语句,也就不会被再次解析和编译)

  -- 语法
  # 定义预处理语句
  PREPARE zongscan_name FROM preparable_zongscan;
  # 执行预处理语句
  EXECUTE zongscan_name [USING @var_name [, @var_name] ...];
  # 删除(释放)定义
  {DROP | DEALLOCATE} PREPARE zongscan_name;


预处理SQL是如何防止SQL 注入的

待执行的 SQL 被编译后存放在缓存池中,DB 执行 execute 的时候,并不会再去编译一次,而是找到 SQL 模板,将参数传递给它然后执行。

所以类似于 or 1==1 的命令会当成参数传递,而不会进行语义解析执行。

 -- 预处理编译 SQL ,会占用资源
 PREPARE zongscan1 from 'SELECT COUNT(*) FROM users WHERE PASSWORD = ? AND user_name = ?';
 set [@a](https://www.zongscan.com/demo777/cat_id/1.html) = 'name1 OR 1 = 1';
 set @b = 'pwd1';
 EXECUTE zongscan1 USING @b,[@a](https://www.zongscan.com/demo777/cat_id/1.html);
 -- 使用 DEALLOCATE PREPARE 释放资源
 DEALLOCATE PREPARE zongscan1;

  • 上一条:
    namesilo域名+香港服务器+acme.sh给网站生成免费ssl证书流程步骤
    下一条:
    在go语言中设置源IP地址后在发出HTTP请求示例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • mysql5.7中实现分区表及分区where in查询示例及分区分表对比浅析(0个评论)
    • mysql中sql_mode的各模式浅析(0个评论)
    • 预处理之SQL参数化查询是如何防止SQL注入的浅析(0个评论)
    • 使用Navicat把mysql5.7版本的数据库导入至mysql8.1版本中流程步骤(0个评论)
    • 在mysql中设置表字段中COLLATE、CHARSET详解(0个评论)
    • 近期文章
    • mysql5.7中实现分区表及分区where in查询示例及分区分表对比浅析(0个评论)
    • nginx + vue配置实现同域名下不同路径访问不同项目(0个评论)
    • 在laravel框架中的5个HTTP客户端技巧分享(0个评论)
    • 在go语言中使用FFmpeg库实现PCM音频文件编码为mp3格式文件流程步骤(0个评论)
    • gopacket免安装Pcap实现驱动层流量抓包流程步骤(0个评论)
    • 在laravel项目中实现密码强度验证功能推荐扩展包:password-strength(0个评论)
    • 在go语言中用filepath.Match()函数以通配符模式匹配字符串示例(0个评论)
    • Laravel Response Classes 响应类使用优化浅析(0个评论)
    • mysql中sql_mode的各模式浅析(0个评论)
    • 百度文心一言今天发布,个人第一批内测体验记录,不好别打我(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客