[SQL]SQL注入与SQL执行过程(基于JDBC)

简介: 本文介绍了SQL注入的概念及其危害,通过示例说明了恶意输入如何导致SQL语句异常执行。同时,详细解释了SQL语句的执行过程,并提出了使用PreparedStatement来防止SQL注入的方法。

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://developer.aliyun.com/article/1635138
出自【进步*于辰的博客

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

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关键字。

SQL语句执行过程

推荐一篇博文:# (二)全解MySQL:一条SQL语句从诞生至结束的多姿多彩历程!(转发)。

那位博主讲述的很详细,我简单总结一下。

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

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

“执行判断”中一个需要注意的问题:
访问数据库时,只要重新执行sql语句即可实现刷新(重新访问),可实际上无法实现。因为sql语句执行后,会生成临时表,如果连接未关闭,临时表就仍然存在。在重新执行相同sql语句时,不会访问数据库,即无法实现刷新。

如何防止“SQL注入”?

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

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

原理:

  1. PreparedStatement 类属于预编译。在实例化时,即conn.preparedStatement(sql),载入了sql语句,故在程序中完成了 验证编译
  2. Statement 类是将变量==拼接进sql语句==;而PreparedStatemet 类是为变量==提供占位符“?”供变量赋值==,这些变量称为“预变量”。
    当为“预类型”为 String 的占位符赋值时,无论变量值包含什么,都会将其视为字符串,也解决SQL注入问题。
    -注:当使用 PreparedStatement 类时,由于变量位置由占位符代替,摆脱了变量作用域限制,故可实现sql语句的共享。

    最后

    本文中的例子是为了方便大家理解和阐述知识点而简单举出的,旨在阐明知识点,并不一定有实用性,仅是抛砖引玉。

本文完结。

目录
相关文章
|
8月前
|
SQL 存储 数据库
Python 的安全性和测试:什么是 SQL 注入攻击?如何防范 SQL 注入?
Python 的安全性和测试:什么是 SQL 注入攻击?如何防范 SQL 注入?
106 1
|
SQL 安全 关系型数据库
supersqli(SQL注入流程及常用SQL语句)
supersqli(SQL注入流程及常用SQL语句)
189 0
|
8月前
|
SQL 安全 数据库
写一段防止sql注入的sql查询
【1月更文挑战第14天】写一段防止sql注入的sql查询
130 31
|
2月前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
64 4
|
8月前
|
SQL Java 数据库连接
JDBC的连接参数的设置导致rowid自动添加到sql
JDBC的连接参数的设置导致rowid自动添加到sql
61 1
|
3月前
|
SQL
Web for Pentester SQL sql注入靶场
Web for Pentester SQL sql注入靶场
|
3月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
72 0
|
3月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
116 0
|
3月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
54 0
|
3月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
69 0