【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)

https://www.cnblogs.com/cnb-yuchen/p/17955065

出自【进步*于辰的博客

参考笔记一,P52.2/3。

1、SQL注入

大家看这条SQL语句:

String sql = "select * from users where username = '"
+ name + + "' and password = '" + pass + "'";

这是一条由字符串拼接而成的登录SQL语句。当用户名、密码都匹配时,才能查询出用户信息,进而登录成功。

用户名和密码由表单输入,假设一种情况:

name = "yc"
pass = "123' or 1 = 1"

那拼接出的SQL语句就是:

String sql = "select * from users where username = 'yc'
and password = '123' or 1 = 1";

如此,用户名和密码已无效,皆可登录成功。

那到底什么是SQL注入?

“SQL注入”是指恶意输入表单数据,利用程序存在先生成SQL语句,后编译的漏洞,使数据库编译器误将表单数据中的字符串识别为数据库关键字,而导致SQL语句“异常”执行,进而表单失效的问题。

上述例子,pass 中带有"or",本是字符串,但数据库编译器将其识别为or关键字。

2、SQL语句执行过程

需要注意一点,以下整个过程都是在数据库中执行。

  • 第一步:sql传输。表单数据提交,sql语句拼接完成,sql语句从程序传输至数据库;
  • 第二步:验证。验证sql语句是否正确;
  • 第三步:编译。由数据库编译器对sql语句进行编译(具体编译情况,比如:编译后文件类型是什么?存放在哪里?本人暂不清楚,大家用java编译理解就行);
  • 第四步:执行判断。判断内存中是否存在具有相同sql语句的临时表。若存在,获取临时表返回给程序;
  • 第五步:执行。sql语句首次执行,数据库会将sql语句和相应结果集生成并存入临时表。临时表存储于内存,而数据库存储于磁盘,故前者执行速度快于后者。

“执行判断”中一个需要注意的问题:

访问数据库时,只要重新执行sql语句即可实现刷新(重新访问),可实际上无法实现。因为sql语句执行后,会生成临时表,如果连接未关闭,临时表就仍然存在。在重新执行相同sql语句时,不会访问数据库,即无法实现刷新。

3、如何防止“SQL注入”?

(基于JDBC)当执行executexx()时,sql语句会经历以上五个步骤,由于先拼接sql语句再进行编译,故数据库会误将“or”“and”等字符串识别为关键字,从而导致SQL注入问题。

解决方法:将执行对象 Statement 换成 PreparedStatement。

原理:

  1. PreparedStatement 类属于预编译。在实例化时,即conn.preparedStatement(sql),载入了sql语句,故在程序中完成了 验证编译
  2. Statement 类是将变量拼接进sql语句;而PreparedStatemet 类是为变量提供占位符“?”供变量赋值,这些变量称为“预变量”。

    当为“预类型”为 String 的占位符赋值时,无论变量值包含什么,都会将其视为字符串,也解决SQL注入问题。

    -注:当使用 PreparedStatement 类时,由于变量位置由占位符代替,摆脱了变量作用域限制,故可实现sql语句的共享。

本文完结。

[SQL]SQL注入与SQL执行过程(基于JDBC)的更多相关文章

  1. (后端)sql手工注入语句&SQL手工注入大全(转)

    转自脚本之家: 看看下面的1.判断是否有注入;and 1=1;and 1=2 2.初步判断是否是mssql;and user>0 3.判断数据库系统;and (select count(*) f ...

  2. 最新SQL手工注入语句&SQL注入大全

    看看下面的1.判断是否有注入;and 1=1;and 1=2 2.初步判断是否是mssql;and user>0 3.判断数据库系统;and (select count(*) from syso ...

  3. SQL server 注入 和 SQL server 扩展(10.29 第二十九天)

    Step1:检测注入点 Step2: select * from sysobjects   (sysobjects 系统对象表,保存当前数据库的对象) select * from users wher ...

  4. MySQL 中一条 sql 的执行过程

    一条 SQL 的执行过程 前言 查询 查询缓存 分析器 优化器 执行器 数据更新 日志模块 redo log (重做日志) binlog (归档日志) undo log (回滚日志) 两阶段提交 为什 ...

  5. 一文读懂一条 SQL 查询语句是如何执行的

    2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头. 为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其 ...

  6. Sql server注入一些tips

    sql server环境测试: 几个特性: 1.sql server兼容性可以说是最差的. 举例: select x from y where id=1 字符串查询 select x from y w ...

  7. MyBatis 源码分析 - SQL 的执行过程

    * 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...

  8. Oracle SQL语句执行过程

    前言 QQ群讨论的时候有人遇到这样的问题:where子句中无法访问Oracle自定义的字段别名.这篇 博客就是就这一问题做一个探讨,并发散下思维,谈谈SQL语句的执行顺序问题. 问题呈现 直接给出SQ ...

  9. 【MySQL】使用 Optimizer Trace 观察SQL执行过程

    Optimizer Trace 是MySQL 5.6.3里新加的一个特性,可以把MySQL Optimizer的决策和执行过程输出成文本.输出使用JSON格式,便于程序分析和人类阅读. 使用方法 1) ...

  10. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

随机推荐

  1. CF1826D Running Miles

    题目链接 题解 知识点:贪心,前缀和,枚举. 首先考虑一个贪心结论,选择区间端点一定是两个最大值,因此 \(i_1 = l,i_3 = r\) . 考虑变形式子 \((b_l + l) + b_{i_ ...

  2. Spring的接口集合注入功能

    Spring的接口集合注入功能 对于Spring中已经注入的bean, 可以使用Autowired, 通过Map<String, BeanInterface>或List<BeanIn ...

  3. TS内置类型与拓展

    TS内置类型与拓展 TypeScript具有类型系统,且是JavaScript的超集,其可以编译成普通的JavaScript代码,也就是说,其是带有类型检查的JavaScript. 内置类型 Type ...

  4. ORACLE ROLLUP和CUBE介绍

    http://blog.csdn.net/wanghai__/article/details/4817920 ------------------ ROLLUP,是GROUP BY子句的一种扩展,可以 ...

  5. junit使用stub进行单元测试

    stub是代码的一部分,我们要对某一方法做单元测试时,可能涉及到调用第三方web服务.假如当前该服务不存在或不可用咋办?好办,写一段stub代码替代它. stub 技术就是把某一部分代码与环境隔离起来 ...

  6. java使用Timer定时器在指定时间执行程序

    下面是一个利用Timer定时器在每天指定时间执行批处理程序的例子. 有关 java.util.Timer 详细知识请参考API. 值得注意的一点是Timer是单线程顺序执行多个任务的. package ...

  7. FastGateway 发布v0.0.0.5

    FastGateway 发布v0.0.0.5 修复构建错误 修复docker-compose执行目录 修改请求来源分析数据列表展示 update README.md. 增加默认证书 修复构建脚本目录错 ...

  8. Mysql 插入timestamp没有使用默认值问题

    在一次升级过程中,发现Mysql插入数据报了个错 Column 'create_time' cannot be null. 但是看了下这个字段虽然是非null,但是是有默认值的 `create_tim ...

  9. dataclass装饰器

    简介 根据定义dataclass时指"一个带有默认值的可变的namedtuple" 简单来说,就是你定义一个很普通的类,@dataclass装饰器可以 帮你生成__repr__._ ...

  10. auth模块的一些方法

    auth模块 auth模块是cookie和session的升级版,auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象,而 ...